2020.06.09——习题训练五
A - Sum of Odd Integers
题意:给定n和k,求是否存在k个不同的正奇数和为n.
解题思路:n和k奇偶性应相同,且1+3+5+...+2k−1=k^2,故n>=k*k.
ac代码:
#include<iostream> using namespace std; int main(){ long long int t,n,k; cin>>t; while(t--){ cin>>n>>k; if(n>=k*k&&((n%2==0&&k%2==0)||(n%2==1&&k%2==1))){ cout<<"YES"<<endl; } else{ cout<<"NO"<<endl; } } return 0; }
B - Princesses and Princes
题意:数量相同的公主和王子进行匹配,每个公主从自己最心仪的王子(用编号代表)开始优先选择靠前的,若存在未匹配的王子则两人匹配成功,最后国王可以通过增加一位公主的一个心仪王子提高匹配对数.
解题思路:用map标记王子是否匹配过,若未匹配过就和当前公主匹配;若当前公主最后没有匹配成功,用数组记录,最后使一个未匹配的公主与一个未匹配的王子匹配即可.
ac代码:
#include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<map> using namespace std; int a[500000],b[500000];//b数组记录未匹配成功的公主 int main(){ int t,n,k,j,max,c,p,i; cin>>t; map<int,int>mp; while(t--){ cin>>n; p=0; mp.clear(); for(i=1;i<=n;i++){ cin>>k; for(j=1;j<=k;j++){ cin>>a[j]; } c=0; for(j=1;j<=k;j++){ if(mp[a[j]]!=1){//判断王子是否匹配 mp[a[j]]=1; c=1; break; } } if(c==0){ p++; b[p]=i; } } if(p==0){ cout<<"OPTIMAL"<<endl; continue; } cout<<"IMPROVE"<<endl; for(i=1;i<=n;i++){ if(mp[i]!=1){ cout<<b[1]<<" "<<i<<endl; break; } } } return 0; }
C - EhAb AnD gCd
题意:已知一个正整数x,求任意两个正整数a和b,使GCD(a,b)+LCM(a,b)=x.
解题思路:直接输出1和x-1即可.
ac代码:
#include<iostream> #include<map> #include<algorithm> using namespace std; int main(){ int t,x; cin>>t; while(t--){ cin>>x; cout<<"1 "<<x-1<<endl; } return 0; }
D - CopyCopyCopyCopyCopy
题意:给定数组,可以改变顺序,求最大递增子序列的长度.
解题思路:对数组排序,遍历非重复的元素的个数即可.
ac代码:
#include<iostream> #include<map> #include<algorithm> using namespace std; long long int a[100005]; int main(){ long long int t,n,i,sum; cin>>t; map<int,int>mp; while(t--){ cin>>n; mp.clear(); for(i=1;i<=n;i++){ cin>>a[i]; mp[a[i]]++; } sort(a,a+n); sum=0; for(i=1;i<=n;i++){ if(mp[a[i]]>=1){ sum++; mp[a[i]]=-100; } } cout<<sum<<endl; } return 0; }
F - Yet Another Tetris Problem
题意:给定一组数,每次操作可以在任何一个元素加上 2,判断最后是否可以使得所有元素相等.
解题思路:发现对数组进行排序,若相邻数相差为2的倍数满足要求,那么判断所有元素奇偶性是否相等即可.
ac代码:
#include<iostream> #include<map> #include<algorithm> using namespace std; int main(){ int t,n,i,a,c,d; cin>>t; while(t--){ cin>>n; c=0; d=0; for(i=0;i<n;i++){ cin>>a; if(a%2==0){ c++; } else{ d++; } } if(c==n||d==n){ cout<<"YES"<<endl; } else{ cout<<"NO"<<endl; } } return 0; }
G - Yet Another Palindrome Problem
题意:给定数组,判断是否存在不改变顺序的且长度大于3的回文子数组.
解题思路:记录数组元素,只要存在相同元素之间位置相差大于1即可.
ac代码:
#include<iostream> #include<map> #include<cmath> using namespace std; int main(){ int t,n,i,b,a,c; cin>>t; map<int,int>mp; while(t--){ cin>>n; mp.clear(); b=0; for(i=1;i<=n;i++){ cin>>a; if(mp[a]==0){ mp[a]=i; } else{ c=i-mp[a]; if(c>1){ b=1; } } } if(b==1){ cout<<"YES"<<endl; } else{ cout<<"NO"<<endl; } } return 0; }
H - Frog Jumps
题意:青蛙在0位置要跳到n+1的位置,0到n+1之间有长为n的,只包含L或R的字符串,L为往左跳,R为向右跳,每次最多跳d的长度,求d的最小值.
解题思路:青蛙想要到达n+1的位置,必须往右跳,那么要保证青蛙能跳过最长的L堆,则找到最多的连续L的个数即可.
ac代码:
#include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<map> using namespace std; char s[300000]; int main(){ int t,i,m,n,max; cin>>t; while(t--){ cin>>s; m=strlen(s); n=0; max=0; for(i=0;i<m;i++){ if(s[i]=='L'){ n++; } else if(s[i]=='R'){ if(max<n){ max=n; } n=0; } } if(n>max){ max=n; } cout<<max+1<<endl; } return 0; }