2020.5.26 习题训练三
Posted ccccrack
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020.5.26 习题训练三相关的知识,希望对你有一定的参考价值。
A - Sorted Adjacent Differences
题意:给出一个长度为n的序列,要求将序列排序,使每两个数之差的绝对值按升序排列
做法:思维题,先sort排序,从中间开始取,往两边推,各取一个,排出来自然满足条件
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #include<set> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; int a[200005]; int main(){ int t; cin >> t; while(t--){ int n; cin >> n; for(int i = 0;i < n;i++){ cin >> a[i]; } sort(a,a+n); int num = 0; for(int i = n/2-1,j = i+1;i >= 0;i--,j++){ cout << a[j] << " " << a[i] << " "; } if(n % 2 != 0){ cout << a[n-1]; } cout << endl; } }
B - Powered Addition
题意:给一串数列,规定第x秒可以使序列中任意的数增加2^x-1,求最少用几秒使其变成一个升序的序列
做法:关键是可以在随意位置加2^x-1,所以只需要找出这个序列中前面的数和后面的数递减的最大差,之后列方程
2^1+……+2^x-1 >= 最大差求x即可
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #include<set> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; LL a[200005]; int main(){ int t; cin >> t; while(t--){ int n; cin >> n; LL k = 0,r = 0; cin >> a[0]; LL pi = a[0]; for(int i = 1;i < n; i++){ cin >> a[i]; pi = max(pi,a[i]); if(pi>a[i]){ r = max(r,pi-a[i]); } } LL j = 1,res = 0; while(r > 0){ r -= j; j *= 2; res++; } cout << res << endl; } }
C - Middle Class
做法:将序列排序后,从后面开始往前求和,之后将和减去x,再往前求,再减x,直到求的和小于x为止
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #include<set> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; int a[200005]; int main(){ int t; cin >> t; while(t--){ int n,x; cin >> n >> x; for(int i = 0;i < n;i++){ cin >> a[i]; } sort(a,a+n); int ans = 0; LL sum = 0; for(int i = n - 1;i >= 0;i--){ if(sum + a[i] - x >= 0){ sum = sum + a[i] - x; ans++; }else{ break; } } cout << ans << endl; } }
D - Circle of Monsters
做法:想要射击的最少就像玩祖玛一样,要充分利用爆炸伤害,关键是要选一个起点,这个起点的要求就是要是要收到来自上一个爆炸伤害最低的那个怪,也就是最难被炸死的,只要这个被我们打死了,剩下的就可以产生最大的爆炸伤害
所以计算子弹的公式就是
怪物的总血量-爆炸产生的总伤害+爆炸伤害最小的爆炸伤害(因为接受这次伤害的怪物被第一只打死了)
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #include<set> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; LL a[300005],b[300005]; LL c[300005]; int main(){ int t; cin >> t; while(t--){ int n; cin >> n; LL sum = 0; for(int i = 0;i < n;i++){ scanf("%lld %lld",&a[i],&b[i]); sum += a[i]; } LL ans = 1e18; LL ex = 0; for(int i = 0;i < n-1;i++){ c[i] = min(b[i],a[i+1]); ex += c[i]; ans = min(ans,c[i]); } c[n-1] = min(b[n-1],a[0]); ans = min(ans,c[n-1]); ex += c[n-1]; cout << sum - ex + ans << endl; } }
E - Kind Anton
题意:给出两个序列,一个a只包含{1,-1,0},一个b含整数,问是否可以通过使a中一个数加上它前面任何数使a变成b
做法:首先需要标记,一旦前面有1或者-1了就行,之后从后往前循环,a>b就-1,a<b就+1,如果有一个不行就break
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #include<set> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; int a[200005],b[200005]; int vis1[200005],vis2[200005]; int main(){ int t; cin >> t; while(t--){ int n; cin >> n; int flag1 = 0,flag2 = 0; memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); for(int i = 0;i < n;i++){ cin >> a[i]; if(flag1 == 1){ vis1[i] = 1; } if(flag2 == 1){ vis2[i] = 1; } if(a[i] == 1){ flag1 = 1; }else if(a[i] == -1){ flag2 = 1; } } for(int i = 0;i < n;i++){ cin >> b[i]; } int flag = 0; for(int i = n-1;i >= 0;i--){ flag = 0; if(a[i] > b[i]){ if(vis2[i] == 1){ flag = 1; } } else if(a[i] < b[i]){ if(vis1[i] == 1){ flag = 1; } } else if(a[i] == b[i]){ flag = 1; } if(flag == 0){ cout << "NO" << endl; break; } } if(flag == 1){ cout << "YES" << endl; } } }
至于f………………看了题解半天也没看明白什么意思,与其直接复制代码还不如等大佬讲题……
以上是关于2020.5.26 习题训练三的主要内容,如果未能解决你的问题,请参考以下文章