题意:给出重量为……的n枚硬币,要将其分为两等份,求怎么分,分出来的两堆硬币的重量的绝对值差值最小。
做法:根据规律,最后一个硬币重量一定大于之前所有硬币之和,将最重的硬币划为一组,之后将剩下的分成两组,最后整合即可
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; int main(){ int t; cin >> t; while(t--){ int n; cin >> n; int a = 0,b = 0; a = pow(2,n); for(int i = 1;i < n/2;i++){ a += pow(2,i); } for(int i = n/2;i < n;i++){ b += pow(2,i); } int ans; ans = abs(a-b); cout << ans << endl; } }
题意:给出一个数组和k,要求完美数组,即连续k个数之和相同。
做法:需要扩充数列,但存在无法扩充的情况,即数组中数的种类大于k的话是无法构造的(无法保证以k为长度的子序列包含所有数,即无法保证和均相同),如果小于k,可以构造;因为题目没有规定构造的子序列长度,所以多长都行,可以直接把n*m作为长度,之后每个子序列把所有出现的数都安排一个上去,数量不够就找一个之前没有出现过的数补上(我懒,直接用的 n,严格意义上讲不对)。
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; int a[200],m[200]; int main(){ int t; cin >> t; while(t--){ int n,k; int x; memset(a,0,sizeof(a)); memset(m,0,sizeof(m)); int num = 0; cin >> n >> k; for(int i = 1;i <= n;i++){ cin >> x; if(a[x] == 0){ a[x] = 1; num++; m[num] = x; } } if(num > k){ cout << -1 << endl; }else{ cout << n*k << endl; for(int h = 1;h <=n;h++){ for(int i = 1;i <= num;i++){ cout << m[i] << ‘ ‘; } for(int i = 0;i < k-num;i++){ cout << n << ‘ ‘; } } cout << endl; } } }
题意:可以分别付a刀和b刀对输入的x和y做出两种操作,一种是给其中一个数加一或减一,还有一种是给两个同时加一或减一,求最少的钱将两个数都变成0
做法:两种方案,一种是全付a刀一个一个减,还有一种是先用b刀方案把最少的那个数减成0,再用a刀方案减剩下的数,两个方案对比找花钱最少的就行
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; int main(){ int t; cin >> t; while(t--){ LL x,y; cin >> x >> y; LL a,b; cin >> a >> b; LL sum1,sum2; sum1 = (x+y)*a; sum2 = min(x,y)*b + a*(max(x,y)-min(x,y)); LL ans; ans = min(sum1,sum2); cout << ans << endl; } }
做法:如果序列只包含一个数,那就输出其本身就好,因为题目并未规定输出的成品序列要多长,多长都行;如果同时包含0和1,那他的最短周期就是01,输出出来就行
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; char s[3000]; int main(){ int t; cin >> t; while(t--){ scanf("%s",&s); int flag = 1; for(int i = 0;i < strlen(s)-1;i++){ if(s[i] != s[i+1]){ flag = 0; break; } } if(flag == 0){ for(int i = 0;i < strlen(s);i++){ cout << "01" ; } cout << endl; }else{ cout << s << endl; } } }
题意:抛弃题目背景,问的就是给出a、b、c、d和n,求可否讲a-b到a+b这个区间乘n,使之与c-d到c+d产生交集
做法:直接算,求出所需两个范围之后,只需要比较断点值大小即可
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; int main(){ int t; cin >> t; while(t--){ int a,b,c,d,n,a1,b1,c1,d1; cin >> n >> a >> b >> c >> d ; a1 = (a-b)*n; b1 = (a+b)*n; c1 = c-d; d1 = c+d; if((a1 >= c1 && a1 <= d1)||(b1 >= c1 && b1 <= d1)||(a1 <= c1 && b1 >= d1)) cout << "Yes" << endl; else cout << "No" << endl; } }
题意:给出一串山峰值,之后给定一个范围,若其中一个值大于其两边的值(和极大值差不多),就算是巅峰,之后问在这串山峰值中,连续k个里面,巅峰数最多的区间所含的被巅峰分割的区域(就是巅峰值加一),以及这个区间里最靠左的山峰的坐标,如有相同答案优先输出最左边的
代码:
//去吧马里奥!把AC公主救回来! // ******** // ************ // ####....#. // #..###.....##.... // ###.......###### // ........... // ##*####### // ####*******###### // ...#***.****.*###.... // ....**********##..... // ....**** *****.... // #### #### // ###### ###### #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<string> #include<map> #include<sstream> #include<cstring> #include<vector> #include<iomanip> #include<queue> #define LL long long #define _64 __int64 const double PI = atan(1.)*4.; using namespace std; int a[300000],b[300000] = {0}; int main(){ int t; cin >> t; while(t--){ // memset(a,0,sizeof(a)); // memset(b,0,sizeof(b)); int n,k; int sum = 0,m = 1; int num = 0; cin >> n >> k; for(int i = 1;i <= n;i++ ){ cin >> a[i]; } for(int i = 1;i <= n;i++){ if(a[i] > a[i-1] && a[i] > a[i+1]){ num++; } b[i] = num; } for(int i = 1;i <= n-k+1;i++){ int cnt = b[i+k-2] - b[i]; if(cnt > sum){ m = i; sum = cnt; } } cout << sum+1 << " " << m << endl; } }
原文:https://www.cnblogs.com/CCCCrack/p/12926387.html