2020.6.12--习题五
题意:给出一个数n,如果有k个正奇数和为n就输出YES,否则输出NO
思路:因为时k个奇数相加和为n,所以按照2个奇数相加为偶数判断:
1.n为奇数时,k应为奇数,n为偶数时,k为偶数
2.当k为1时,n应改为奇数才符合条件
3.因为n=1+3+5+7+……=k*1+(k*(k-1)/2)*2=k^2符合等差公式,根据公式可得k<=sqrt(n)
#include<bits/stdc++.h> using namespace std; int main() { int t; scanf("%d",&t); while(t--) { long long n,k,i,j,m=0,ct=0; scanf("%lld%lld",&n,&k); if(n%2!=0&&k==1)cout<<"YES"<<endl; else if((n%2==0&&k==1)||(n%2==0&&k%2!=0))cout<<"NO"<<endl; else if(n%2!=0&&k<=sqrt(n)&&k%2!=0)cout<<"YES"<<endl; else if(n%2==0&&k<=sqrt(n)&&k%2==0)cout<<"YES"<<endl; else cout<<"NO"<<endl; } }
题意:有n个公主,和n个王子,国王要把n个公主匹配给王子,每个公主都有一个清单,公主可以与清单上为匹配过的第一个王子匹配,最后如果有公主未匹配到王子,则任意选择一位公主与未匹配的王子匹配
思路:先将公主和清单上的未匹配的王子匹配,用两个数组记录下已匹配的王子和公主,数组初始化为0,匹配后为1,最后再遍历一遍,看哪个公主为匹配到王子,找出来输出"IMPROVE"和下标即可,若全部匹配完,就输出“OPTIMAL”
#include<bits/stdc++.h> using namespace std; #define maxn 100010 long long s[maxn],b[maxn]={0},w[maxn]={0}; int main() { long long t; scanf("%lld",&t); while(t--) { long long n,k,i,j,p=0; scanf("%lld",&n); for(i=1;i<=n;i++)b[i]=0,w[i]=0;//初始化为0 //cout<<w[1]<<" "<<w[2]<<endl; for(i=1;i<=n;i++){ scanf("%lld",&k); for(j=1;j<=k;j++) scanf("%lld",&s[j]); for(j=1;j<=k;j++){ if(b[s[j]]==0){ b[s[j]]=1;//看s[i]王子是否有了公主,如果没有就和w[i]公主匹配 w[i]=1; //cout<<b[s[j]]<<" "<<s[j]<<" "<<w[i]<<endl; break; } } } //cout<<b[4]<<endl; // cout<<w[1]<<" "<<w[2]<<endl; for(i=1;i<=n;i++)//看是否全部公主都有了匹配的王子 { if(w[i]==0)//当有公主没有匹配到王子时 { p=1; cout<<"IMPROVE"<<endl; for(j=1;j<=n;j++)//遍历找到没有匹配到公主的王子 { //cout<<b[j]<<"*"<<b[4]<<endl; if(b[j]==0){ cout<<i<<" "<<j<<endl; break; } } break; } } if(p==0)cout<<"OPTIMAL"<<endl; } }
题意:给出一个数x,找到a,b使GCD(a,b)+LCM(a,b)=x,GCD指a,b能同时整除的最大整数,LCM指能同时整除a和b的最小整数
思路:当a为1时,GCD(1,b)=1,LCM(1,b)=x-1,所以 b=x-1
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { long long x,a,b; scanf("%lld",&x); printf("1 %lld\n",x-1); } }
题意:给出一个长度为n的数组,创建一个包含这个数组的新数组,并连续写入,求新数组中最长递增子序列长度
思路:直接找出有多少个不同数输出个数即可
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { long long n,i,ct=1; scanf("%lld",&n); long long s[n+5]; for(i=0;i<n;i++)scanf("%lld",&s[i]); sort(s,s+n); for(i=0;i<n-1;i++) { if(s[i]<s[i+1])ct++; } printf("%lld\n",ct); } }
题意:俄罗斯方块:有n个数,从左到右排列,第 i 数代表了第 i 列的初始高度为ai,在这些列的顶部,你只能放置大小为2*1的方块,且不能旋转,通过操作使所有方块消失。有两种操作:1.当数组中任意一项大于0时,可以选择一些i使ai变为ai+2
2.当数列每项都大于0时,数列的每一项都-1
如果最后数组元素都为0,则输出YES,否则输出NO
思路:因为最后都是数组元素同时-1变为0,所以数组元素要+2后都相同,因为元素+2后,奇偶性不变,所以就看数组元素是否全为奇数或全为偶数
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { int n,s[110],i,m=0,j=0; cin>>n; for(i=0;i<n;i++)cin>>s[i]; for(i=0;i<n;i++) { if(s[i]%2==0){ m=1; } else j=1; } if(m==1&&j==0)cout<<"YES"<<endl; else if(j==1&&m==0)cout<<"YES"<<endl; else cout<<"NO"<<endl; } }
G.Yet Another Palindrome Problem
题意:给出一个长度为n的数组a,判断是否有长度至少为3的子序列且该序列为回文
思路:将数组遍历,长度至少为3,所以只需要找到一个长度为3的子序列且为回文 就符合
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { int n; cin>>n; int s[n+5],i,j,ct=0; for(i=0;i<n;i++)cin>>s[i]; for(i=0;i<n-2;i++) { for(j=i+2;j<n;j++) { if(s[i]==s[j]) { ct=1;//i--i+1--i+2长度为3符合 cout<<"YES"<<endl; break; } } if(ct==1)break; } if(ct==0)cout<<"NO"<<endl; } }
题意:一只青蛙最初位于0处,需要从右边一个长度为n的字符串上向右跳到n+1的位置,该字符串由L和R组成,L表示向左跳,R为向右跳,青蛙可以跳入相同的单元格两次,并且可以根据需要执行任意多次的跳动,青蛙一次跳跃不超过d个单元格,找到最小的d,使青蛙可以从0跳到n+1的位置
思路:d初始值为1,青蛙要跳到右边,所以要避免跳到L上,找到连续是L的最大长度ct,d=ct+1
(如果字符串都为R,则d为1,都为L时,d=字符串长度+1)
#include<bits/stdc++.h> #include<iostream> #include<string> using namespace std; #define maxn 200005 char arr[maxn]; long long b[maxn]={1}; int main() { int t; cin>>t; while(t--) { scanf("%s",&arr); long long m,i,j,k=0,ct=1,maxx=-1; m=strlen(arr); //cout<<m<<endl; for(i=0;i<m;i++) { if(arr[i]=='L') { ct++; } else if(arr[i]=='R')ct=1; maxx=max(maxx,ct); } printf("%lld\n",maxx); } }

浙公网安备 33010602011771号