难度1200
题意:给定一个n阶楼梯的高度和可以跨的高度,求最高能走到多高。
思路:思路其实很简单 去找到最大的可以去到的台阶就行了 那么前缀和就是答案了 然后数据范围暴力是肯定不行的 再去想一下 一般求最大满足 最小满足的题目一般都是二分 那么就可以去想想可不可以二分了 这题明显是可以二分的 去维护一个前缀最大值数组就可以二分这个数组了 二分出来的答案就是最大可以到达的最大台阶了
然后有一个小细节 二分的 l 应该从0开始 因为可能会有一个台阶都不能跨的
- #include
- using namespace std;
- const int N=2e5+10;
- int a[N];
- int b[N];
- long long sum[N];
- void solve()
- {
- int n,q;
- cin>>n>>q;
- for(int i=1;i<=n;i++)
- cin>>a[i];
- for(int i=1;i<=n;i++)
- {
- sum[i]=sum[i-1]+a[i];
- b[i]=max(b[i-1],a[i]);
- }
- while(q--)
- {
- int k;
- cin>>k;
- int l=0,r=n;
- while(l
- {
- int mid=l+r+1>>1;
- if(b[mid]>k) r=mid-1;
- else l=mid;
- }
- cout<
" "; - }
- puts("");
- }
- int main()
- {
- int t;
- cin>>t;
- while(t--)
- solve();
- return 0;
- }
难度1300
题意: 一个聚会要从n 个人中邀请一部分人,如果第 i 个人未被邀请,将会获得不高兴值 a[i] 。这 n 个人中有 m 对朋友,每对朋友来了以后,都会吃一个蛋糕。要求吃的蛋糕的数量必须为偶数,求这种条件下的最小不高兴值
思路:由于可以很直接的看出当m为偶数的时候 可以邀请所有人 所以m为偶数的时候一定为0
那既然考虑偶数了 是不是也要考虑一下奇数 如果当m为奇数的时候会有什么操作呢?当m是奇数的时候,我们证明:最多只有两个人无法到场。
为了让边数变回偶数,我们需要删除一些人,记录所有人的度:
那么我们去删除一些人 是不是从删除一个人开始呢?
1.删除一个人 删除一个人使得度数的总和是满足题目要求的,那么删掉的一定是奇数关系的人
2.删除两个人 删除两个人就有几种选择了
(1)删除一个奇数的度的点再删除一个偶数的度的点这样明显不比 1 好 所以直接放弃
(2)删除一个奇数和不与他相邻的奇数 这样会删除偶数个点 放弃
(4)删除一个奇数点和与他相邻的奇数点 这样不比 1 好 放弃
(3)删除一个偶数点和偶数点并且是相邻的 如果不相邻 就不可能删除奇数的边 这种方法是没被统计过的
3.删除三个人及以上是没有办法比删除一个人和两个人的花费能小的 因为删除两个人就一个能构造出一组最小合法解了 删除三个及以上都是在前两个操作上增加花费
上面全部操作取一个min就好了
- #include
- using namespace std;
- const int N=1e5+10;
- int d[N];
- int u[N],v[N];
- int a[N];
- void solve()
- {
- int n,m;
- cin>>n>>m;
- for(int i=1;i<=n;i++)
- cin>>a[i];
- memset(d,0,sizeof d);
- for(int i=1;i<=m;i++)
- {
- int a,b;
- cin>>a>>b;
- u[i]=a,v[i]=b;
- d[a]++,d[b]++;
- }
- if(m%2==0)
- {
- cout<<0<
- return ;
- }
- int minl=0x3f3f3f3f;
- for(int i=1;i<=n;i++)
- if(d[i]%2)
- minl=min(minl,a[i]);
- for(int i=1;i<=m;i++)
- {
- if(d[u[i]]%2==0&&d[v[i]]%2==0)
- {
- minl=min(minl,a[u[i]]+a[v[i]]);
- }
- }
- cout<
- return ;
- }
- int main()
- {
- int t;
- cin>>t;
- while(t--)
- solve();
- return 0;
- }
难度1400
题意:给定两个长度为n的正整数数组a,b,每次操作可以选择任意一个数,转换为其十进制的位数。问至少多少次操作,可以让a,b相似。即通过排序后,两个数组相等
思路:首先可以知道只有大的可以变成小的 小的是不可以变成大的 那么我A序列的最大值只能去和B序列中的比A序列的最大值大的数去匹配 B序列的最大值只能去和A序列中的比B序列的最大值大的数去匹配 如果说两个序列的最大值不相等会有什么情况? 那么这两个序列的最大值的比较大的那个值 肯定是没东西和他匹配的 而这个数一定是要变小的 所以一定要进行上面的操作
那么经过这样的想法是不是诞生了一个贪心想法 是不是如果两个序列的最大值不相同 那么每一步都去让最大值中的那么比较大的去变小 这样的答案一定是有解的但是是不是最优的呢?答案是最优的 因为每次操作都是变的两个序列的最大值 而最大值是一定要去变小的 这样是没有浪费的操作的 所以是最优的
实现的时候用两个优先队列去维护就ok了
- #include
- using namespace std;
- int f(int x)
- {
- int res=0;
- while(x)
- {
- res++;
- x/=10;
- }
- return res;
- }
- void solve()
- {
- int n;
- priority_queue<int,vector<int>> a,b;
- cin>>n;
- for(int i=1;i<=n;i++)
- {
- int x;
- cin>>x;
- a.push(x);
- }
- for(int i=1;i<=n;i++)
- {
- int x;
- cin>>x;
- b.push(x);
- }
- int ans=0;
- while(a.size())
- {
- if(a.top()==b.top())
- {
- a.pop(),b.pop();
- }
- else if(a.top()>b.top())
- {
- int x;
- x=a.top();
- a.pop();
- a.push(f(x));
- ans++;
- }
- else
- {
- int x;
- x=b.top();
- b.pop();
- b.push(f(x));
- ans++;
- }
- }
- cout<
- return ;
- }
- int main()
- {
- int t;
- cin>>t;
- while(t--)
- solve();
- return 0;
- }
-
相关阅读:
STM32 寄存器配置笔记——GPIO配置输出
STM32 寄存器配置笔记——USART配置 打印
研发必会-异步编程利器之CompletableFuture(含源码 中)
入耳式无线蓝牙耳机哪款好?无线入耳蓝牙耳机推荐
数组中第K个最大元素-快速排序,堆排序,优先队列
XML配置文件
一篇让你使用vue-cli搭建SPA项目
【深度学习21天学习挑战赛】备忘篇:我们的神经网模型到底长啥样?——model.summary()详解
jQuery
移动端性能专项测试之内存 - 进阶篇
-
原文地址:https://blog.csdn.net/lee_14141/article/details/127879175