A. Plus One on the Subset
题意:简单题,每次可以选择数组里的任意多的数字进行加一,求要多少次可以使得整个数组里的所有元素相等
思路:直接遍历找到最大值和最小值的差值输出相同即可。
#include<bits/stdc++.h> using namespace std; int a[55]; int main() { int n,i,j,t; cin>>t; while(t--) { cin>>n; int min1=inf,max1=0; for(i=0;i<n;i++) { cin>>a[i]; max1=max(max1,a[i]); min1=min(min1,a[i]); } cout<<max1-min1<<endl; } return 0; }
B. Make AP
题意:给你三个数字x,y,z问选择任意一个数字乘以任意数之后,能否使得序列为一个等差数列。
思路:感觉写复杂了,枚举一下三种可能性就行,已知任意两个数,假设他们为等差,那么第三个数是固定的,判断是不是原数的因子即可。
#include<bits/stdc++.h> using namespace std; bool jg(int x,int y,int z) { if(x==y&&y==z) return true; if(x+z==2*y&&((z>y&&y>x&&z-y==y-x)||((x>y&&y>z&&x-y==y-z)))) return true; return false; } int main() { int n,i,j,t,x,y,z; cin>>t; while(t--) { cin>>x>>y>>z; if((x+z)%2==0&&(((x+z)/2)%y==0)&&jg(x,(x+z)/2,z)) { // cout<<x<<" "<<(x+z)/2<<" "<<z<<endl; scYES; } else if(2*y-z>0&&(2*y-z)%x==0&&jg(y-(z-y),y,z)) { // cout<<2*y-z<<" "<<y<<" "<<z<<endl; scYES; } else if(2*y-x>0&&(2*y-x)%z==0&&jg(x,y,y+(y-x))) { // cout<<x<<" "<<y<<" "<<2*y-x<<endl; scYES; } else { scNO; } } return 0; }
C. Division by Two and Permutation
题意:给出一个数组a,每次操作会使数组里的元素/2,求最后能否变成从1~n的全排列。
思路:直接暴力模拟,只要当前数字能变成1~n里的数就行,能变成就标机一下,然后继续,我之前卡住了,还以为是将当前数字能划分的所有数字当成一组,然后每组只能选一个,我就以为是个分组的背包,但是不懂怎么递归下去,然后发现不行,浪费了很多时间,看完这个思路也没懂,为什么这个打标机的操作没有先后呢? 猜过的ε=(´ο`*)))唉
#include<bits/stdc++.h> using namespace std; const int maxn=55; int a[maxn]; vector<int >m1[maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int n,i,j,t; map<int,int >mo; cin>>t; while(t--) { cin>>n; mo.clear(); bool ok=0; for(i=1;i<=n;i++) { cin>>a[i]; while(1) { if(mo[a[i]]==0&&a[i]>=1&&a[i]<=n) { mo[a[i]]++; break; } else if((mo[a[i]]!=0||(a[i]>n))&&a[i]!=0) { a[i]/=2; } else if(a[i]==0) { ok=1; break; } } } if(ok==1) scNO else scYES; } return 0; }
D. Palindromes Coloring
题意:其实可以把这题抽象一下,就是把一个字符串拆成k个子串,输出所有子串里回文子串的最大长度的最小值
思路:不难想到可以先把字母都以2为长度划分一下,这样可以一起划分到一个新的字符串都能构成回文串,但是如果有个字母长度为奇数,那么该字符串一定都作为k个答案的母串,但是还有一种情况容易漏,就是假设现在有5对a,我需要拆成3个串,那么我可能会拆成
aa aa
aa aa
aa
这样最短的长度是2,但其实并不是最优的,虽然5/3=1,意思是5对字母分成三个字符串,刚好可以每个字符串分一对aa,但是5%3=2
还多余了两对,再把这两对*2,就是还多了四个字母,很明显4个字母是大于k的
所以正确的划分应该是
aa aa
aa a
aa a
这样长度就是3了,所以只要为奇数的字符串的数量+能拆成的偶数对数*2%k之后的字符数量大于k,就可以多凑一排了
#include<bits/stdc++.h> using namespace std; int main() { map<char ,int >mo; string s1; int n,i,j,t,k; cin>>t; while(t--) { mo.clear(); cin>>n>>k>>s1; int cnt=0,sum=0; for(i=0;i<n;i++) { mo[s1[i]]++; } for(auto &[a,b]:mo) { if(b%2==1) { cnt++; } sum+=(b/2); } int ans=sum/k*2; if((sum%k)*2+cnt>=k) ans++; cout<<ans<<endl; } return 0; }