给你一个x,y,问你能否对x通过乘以a次b可以得到y的方案,可以输出a和b即可(答案不唯一),如果不可以,输出0 0。
思路分析:略
代码:#include#include #include using namespace std; int t, a, b, x, y; int main() { cin >> t; while(t --){ cin >> x >> y; if(y % x){ cout<<"0 0"<<'n'; } else{ cout<<"1 "< B. Dictionary 原题: 题目大意:
根据题意对给定的字符串输出其对应的下标即可。
思路分析:略
代码:#includeC. Infinite Replacement 原题: 题目大意:#include #include using namespace std; int t; string tmp; int main() { cin >> t; while(t -- ){ cin>>tmp; int ans = 0; ans = (tmp[0] - 'a') * 25; if(tmp[1] > tmp[0])ans += tmp[1] - 'a'; else ans += tmp[1] - 'a' + 1; cout << ans << 'n'; } return 0; } 给定一个字符串s和字符串t,字符串都是由a字符构成,我们通过t取替换s中字符a的地方,能够得到多少方案。如果会无限循环输出-1,反之输出方案即可。
思路分析:分类讨论:
1)如果t = ‘a’; 那么就一种方案 1
代码:
2)如果t 中有’a’, 每次替换s的时候都会多一个a,会无限循环,那么就 - 1
3)如果t 中没有a, 就是每次替换s的方案数,即 2^len#includeD. A-B-C Sort 原题:#include #include using namespace std; int q; string s, t; long long jc(int n){ long long ans = 1; for(int i = 1; i <= n; i ++)ans *= 2; return ans; } int main() { cin >> q; while(q --){ cin >> s; cin >> t; int flag = 0, len = t.size(), len2 = s.size(); for(int i = 0; i < len; i ++){ if(t[i] == 'a'){ flag = 1; break; } } if(t.size() == 1 && flag)cout<<"1"<<'n'; else if(flag)cout<<"-1"<<'n'; else { long long ans = jc(len2); cout << ans<< 'n'; } } return 0; } 题目大意:
先后对a数组和b数组进行操作,问能否使得得到的c是非递减的。
操作:
思路分析:对a数组考虑,可以发现,最前面的数肯定是先被c取到放到最后面的数
如果要让最后的c数组是非递减的,必须满足:
如果初始a数组的长度n是偶数:t == 2;
如果初始a数组的长度n是奇数:t == 1;
1)t == 1时,下标idx数的大小要小于等于idx + 2和idx + 3
代码:
- t == 2时,下标idx数的大小要小于等于idx + 1和idx + 2
#includeE. Breaking the Wall 原题:#include #include using namespace std; const int N = 1e6 + 5; int t, n; int a[N]; int main() { cin >> t; while(t --){ cin >> n; for(int i = 1; i <= n; i ++)cin >> a[i]; int flag = 1, t = 1; if(n % 2)t = 2; for(int idx = 1; idx <= n; idx ++){ if(t == 1){ t = 2; if(a[idx] > a[idx + 2] && idx + 2 <= n){ flag = 0; break; } if(a[idx] > a[idx + 3] && idx + 3 <= n){ flag = 0; break; } } else if(t == 2){ t = 1; if(a[idx] > a[idx + 1] && idx + 1 <= n){ flag = 0; break; } if(a[idx] > a[idx + 2] && idx + 2 <= n){ flag = 0; break; } } } if(flag)cout << "YES" << 'n'; else cout << "NO" << 'n'; } return 0; } 题目大意:
有n面墙,问你摧毁任意两座(可以不相连)需要的最少操作数。
每一次操作:可以选择任意一座墙造成2点伤害,并且其左右相邻的墙同时收到1点伤害。
思路分析:分类讨论一下:
1)攻击使相邻两个使两个摧毁:
最优:令两个墙中强度最小为minn,最大为maxx
再次讨论:
1、如果minn * 2 <= maxx
我们直接可以通过用2伤害攻击强大最大的墙,当最大的墙摧毁时,那么较小的那面墙也肯定摧毁了。
2、如果minn * 2 > maxx
用2伤害直接攻击最大强度的墙,肯定会达到两面墙强度相等的时候,然后依次轮流每次攻击一面墙,两面墙的差最多为1,让输出达到最大化,结果肯定能够同时到达0 或者 一个为0 一个为 1,后者就直接再攻击依次就好了。
for(int i = 1; i <= n - 1; i ++){ int maxx = -N, minn = N; maxx = max(a[i], a[i + 1]); minn = min(a[i], a[i + 1]); if(minn * 2 <= maxx){ s1 = min(s1, (maxx + 1) / 2); } else{ s1 = min(s1, (a[i] + a[i + 1] + 2) / 3); } }2)通过攻击中间一个摧毁其旁边两面墙:
最优:枚举所有情况,攻击中间一个墙,如果左右两边有一面墙强度为0了,就直接用2伤害去攻击另一边的墙, 取最小值。
for(int i = 1; i <= n - 2; i ++){ int tmp = min(a[i], a[i + 2]) + (abs(a[i + 2] - a[i]) + 1) / 2; s2 = min(s2, tmp); }3)直接攻击摧毁两个不相邻的墙
最优情况就是找两个强度最小min1和min2的墙,让后分别通过两点伤害就他们摧毁即可。
(min1 + 1) / 2 + (min2 + 1) / 2因为1) 2) 3 )就包含了所有情况,所以答案即取1) 2) 3)的最小值
代码:#includeF. Desktop Rearrangement 原题:#include #include using namespace std; const int N = 1e6 + 10; int n, s1 = N, s2 = N, ans = N; int a[N]; int main() { cin >> n; for(int i = 1; i <= n; i ++)cin >> a[i]; for(int i = 1; i <= n - 1; i ++){ int maxx = -N, minn = N; maxx = max(a[i], a[i + 1]); minn = min(a[i], a[i + 1]); if(minn * 2 <= maxx){ s1 = min(s1, (maxx + 1) / 2); } else{ s1 = min(s1, (a[i] + a[i + 1] + 2) / 3); } } for(int i = 1; i <= n - 2; i ++){ int tmp = min(a[i], a[i + 2]) + (abs(a[i + 2] - a[i]) + 1) / 2; s2 = min(s2, tmp); } sort(a + 1, a + n + 1); ans = min({s1, s2, (a[1] + 1) / 2 + (a[2] + 1) / 2}); cout << ans << 'n'; return 0; } 题目大意:
加删图标,问排列整齐最少需要几步。
整齐:从左往右依次排数列,排满一列排下列。
思路分析:分类讨论,维护不需要排的数量,答案就是总图标数减去不需要排的图标数。
代码:#include#include #include #include



