2020.6.2--习题四
Posted mxw000120
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020.6.2--习题四相关的知识,希望对你有一定的参考价值。
A - Dreamoon and Ranking Collection
题意:给出n个排名,x个将要进行的比赛数,这x个排名可以任意给出,使名次能为1 2 3 ..v连续的一组数,选取恰当的数使v最大
先将已知排名作为下标且值为1,其余为0,再从1开始筛选数组,其中不为1的赋值为1并记录个数,当个数达到x个时跳出;再将数组重新筛选,遇到0时跳出,最终结果为 i-1;
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { int n,x; cin>>n>>x; int m,i,j,ct=0,b[1010]={0}; for(i=1;i<=n;i++) { cin>>m; b[m]=1; } for(i=1; ;i++) { if(b[i]==0) { ++ct; b[i]=1; } if(ct==x)break; } int k=0; for(i=1; ;i++) { if(b[i]==0) { k=i-1; break; } } cout<<k<<endl; } }
B - Dreamoon Likes Permutations
给出一个长为n的序列,要求把它分成两部分,两部分均为一个连续的自然数列,问能有几种分法,给出分出来的两部分序列长度。
设这个序列最大值为ma,那么必定有一部分的长度为ma,因为是自然数列数应该从1到ma不重样,所以长度为ma,那么另一部分的长度就是n-ma了,所以我们尝试把序列分成ma和n-ma两个部分,如果ma不是n的一半的话尝试分成n-ma和ma两个部分,设一部分的长度为len,我们只要用个标记数组看1到len是否全部出现即可。
#include<iostream> using namespace std; const int maxn=2e5+5; int a[maxn],vis[maxn],ans[5][5]; int t,cnt,n,ma; bool check(int l1,int l2){ for(int i=1;i<=n;i++) vis[i]=0; for(int i=1;i<=l1;i++) vis[a[i]]=1; for(int i=1;i<=l1;i++){ if(vis[i]==0) return 0; } for(int i=1;i<=n;i++) vis[i]=0; for(int i=l1+1;i<=n;i++) vis[a[i]]=1; for(int i=1;i<=l2;i++){ if(vis[i]==0){ //cout<<"**** "; return 0; } } return 1; } int main() { cin>>t; while(t--){ cin>>n; ma=-1; for(int i=1;i<=n;i++){ cin>>a[i]; ma=max(ma,a[i]); } cnt=0; if(check(ma,n-ma)){ cnt++; ans[cnt][1]=ma; ans[cnt][2]=n-ma; } if(ma*2!=n&&check(n-ma,ma)){ cnt++; ans[cnt][1]=n-ma; ans[cnt][2]=ma; } printf("%d ",cnt); for(int i=1;i<=cnt;i++){ printf("%d %d ",ans[i][1],ans[i][2]); } } return 0; }
C - Exercising Walk
题意:有一只猫,开始位置在(x,y),向左右下上分别走a,b,c,d步,可以按任意顺序走,同一个方格可以反复经过,但不能超过(x1,y1)~(x2,y2)这个界限,如果可以安排合理则输出Yes否则输出No
当(x1==x&&x2==x&&a+b!=0)||(y1==y&&y2==y&&c+d!=0) 直接输出No
其余情况下:无论向左还是向右走多少下,最终x=x-a+b,同理y=y-c+d;只要此时x,y都在(x1,y1)~(x2,y2)这个界限内,就输出Yes,否则No
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { long long a,b,c,d,x,y,x1,x2,y1,y2; scanf("%lld%lld%lld%lld",&a,&b,&c,&d); scanf("%lld%lld%lld%lld%lld%lld",&x,&y,&x1,&y1,&x2,&y2); if((x1==x&&x2==x&&a+b!=0)||(y1==y&&y2==y&&c+d!=0))cout<<"No"<<endl; else{ x=x-a+b; y=y-c+d; // cout<<x<<" "<<y<<endl; if(x>=x1&&x<=x2&&y>=y1&&y<=y2)cout<<"Yes"<<endl; else cout<<"No"<<endl; } } }
D - Composite Coloring
题意: 用不超过11种颜色给合数数组染色,保证同色的数不互质。
题解: 数组范围1000以内,而100以内的质数共11个。素因子分解按照最小素因子分配颜色。
#include <bits/stdc++.h> using namespace std; int res[1010]; map<int,int> mp; int main(){ int t; cin>>t; while(t--){ int n; cin>>n; int cnt=0; mp.clear(); for(int i=0,a;i<n;i++){ cin>>a; for(int j=2;j<=sqrt(a);j++){ if(a%j==0){ if(mp[j])res[i]=mp[j]; else res[i]=mp[j]=++cnt; break; } } } cout<<cnt<<" "; for(int i=0;i<n;i++) cout<<res[i]<<" "; cout<<" "; } return 0; }
E - K-th Beautiful String
题意:给一个长度n的ab字符串,要求包含(n-2)个a和2个b,进行字典序排列,求第k个字符串
思路:
通过找规律,第一个b在倒数第二位有1个,倒数第三位2个,倒数第四位三个,第二个b的位置就是k-1-2-3-...剩下的数字倒着数,循环
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { long long n,k,i,j; scanf("%lld%lld",&n,&k); char s[n+10]; for(i=1;i<n;i++) { if(k<=i)break; else k-=i; } i=n-i; k=n-k+1; for(j=1;j<=n;j++) { if(j==i||j==k) { cout<<"b"; } else cout<<"a"; } cout<<endl; } }
F - Carousel
题意: 一个圈中,相邻的不同元素要涂成不同颜色,问最多需要多少种颜色可涂满,并写出涂法
要使答案为1,显然只有一种情况,就是整个序列只有一种动物。
要使答案为2。先把序列里每一段极长的、相同动物的连续段用同一种颜色表示,把相邻的段涂上不同的颜色(例如:上一段是1,这一段就是2;上一段是2,这一段就是1)。
此时,还需要考虑的只有1和n的关系。若1和n是同一种动物,或者它们现在已经是不同的颜色了,则说明当前的涂色方法就是一个合法解。
否则,我们要做一些调整,使1和n颜色不同。我们检查序列里是否存在一个同色段的长度大于1。如果存在,则我们可以把这一段劈成两半,前一半还是原来的颜色,后一半和原来颜色相反,且从它往后的每一段颜色都和原来反转。这样,1和n就一定不同色了。
如果找不到长度大于1的同色段。说明我们无法用22种颜色构造出合法解。即答案为3。我们直接在原来构造的基础上令n的颜色为3即可。
#include <bits/stdc++.h> using namespace std; #define pb push_back #define mk make_pair #define lob lower_bound #define upb upper_bound #define fi first #define se second #define SZ(x) ((int)(x).size()) typedef unsigned int uint; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; namespace Fread{ const int MAXN=1<<20; char buf[MAXN],*S,*T; inline char getchar(){ if(S==T){ T=(S=buf)+fread(buf,1,MAXN,stdin); if(S==T)return EOF; } return *S++; } }//namespace Fread #ifdef ONLINE_JUDGE #define getchar Fread::getchar #endif inline int read(){ int f=1,x=0;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } inline ll readll(){ ll f=1,x=0;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } /* ------ by:duyi ------ */ // myt天下第一 const int MAXN=2e5; int n,a[MAXN+5],col[MAXN+5]; bool check1(){ for(int i=1;i<=n;++i){ int j=i%n+1; if(a[i]!=a[j])return 0; } puts("1"); for(int i=1;i<=n;++i)printf("%d ",1);puts(""); return 1; } bool check2(){ col[1]=1; for(int i=2;i<=n;++i){ if(a[i]!=a[i-1]){ col[i]=3-col[i-1]; } else{ col[i]=col[i-1]; } } if((a[n]==a[1])||(a[n]!=a[1]&&col[n]!=col[1])){ puts("2"); for(int i=1;i<=n;++i)printf("%d ",col[i]);puts(""); return 1; } for(int i=1;i<n;++i)if(a[i]==a[i+1]){ col[i+1]=3-col[i]; for(int j=i+2;j<=n;++j){ if(a[j]!=a[j-1]){ col[j]=3-col[j-1]; } else{ col[j]=col[j-1]; } } puts("2"); for(int i=1;i<=n;++i)printf("%d ",col[i]);puts(""); return 1; } return 0; } void check3(){ col[1]=1; for(int i=2;i<=n;++i){ if(a[i]!=a[i-1]){ col[i]=3-col[i-1]; } else{ col[i]=col[i-1]; } } col[n]=3; puts("3"); for(int i=1;i<=n;++i)printf("%d ",col[i]);puts(""); } int main() { int T=read();while(T--){ n=read(); for(int i=1;i<=n;++i)a[i]=read(); if(check1())continue; if(check2())continue; check3(); } return 0; }
以上是关于2020.6.2--习题四的主要内容,如果未能解决你的问题,请参考以下文章