2020.06.01 习题训练四
A - Dreamoon and Ranking Collection
题意:就是数数,给你一组数,还告诉你有多少个万能数(可成为任意数得数字),问通过数数1,2,3……最多能数到多少
思路:题目给的范围不是很大,我就从头开始遍历,先给这组数字进行排序,然后再遍历从1开始找,如果数字中有这个数就不需要了消耗万能数,如果没有就需要消耗,知道消耗完这些万能数
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 using namespace std; 7 int main(){ 8 int t; 9 scanf("%d",&t); 10 while(t--){ 11 int n,x; 12 int a[210]={0}; 13 int num; 14 scanf("%d %d",&n,&x); 15 for(int i=0;i<n;i++){ 16 scanf("%d",&num); 17 a[num]++; 18 } 19 int i=1; 20 int s; 21 for(i=1;i<210;i++){ 22 if(a[i]==0){ 23 x--; 24 } 25 if(x==0){ 26 s=i; 27 for(int j=i;j<210;j++){ 28 if(a[j]==0){ 29 break; 30 }else{ 31 s=j; 32 } 33 } 34 } 35 } 36 37 printf("%d\n",s); 38 } 39 }
B - Dreamoon Likes Permutations
题意:给出一组数,进行让你分成两组,使得这两组变成含有i个数,并且数字元素从1-i每个出现1次,问能够有多少种方式分成这样
思路:从头开始找1-i(i<=n),是否满足题目中的条件,从头开始遍历找到所有满足条件的i,然后倒过来找i-n满足条件的,就是寻找从头开始找到的i和从尾开始找到的i是否相同,相同就是两边都可以满足题目要求
wa掉的/应该注意的:1.应该把问题分开来满足可能会更简单点,再去找
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #define LL long long 7 #define _64 __int64 8 const double PI = atan(1.)*4.; 9 using namespace std; 10 int main(){ 11 int t; 12 scanf("%d",&t); 13 while(t--){ 14 int a[200009]={0}; 15 int vis1[200009]={0}; 16 int vis2[200009]={0}; 17 int f1[200009]={0}; 18 int f2[200009]={0}; 19 int n; 20 scanf("%d",&n); 21 for(int i = 1;i <= n;i++){ 22 scanf("%d",&a[i]); 23 } 24 int num1 = 0; 25 int maxx = 0; 26 for(int i=1;i<=n;i++){ 27 maxx = max(maxx,a[i]); 28 if(vis1[a[i]]==1){ 29 continue; 30 } 31 if(a[i]<=maxx){ 32 vis1[a[i]]=1; 33 num1++; 34 } 35 if(num1==maxx&&num1==i){ 36 f1[i] = 1; 37 } 38 } 39 int num2=0; 40 int maxn2=0; 41 for(int i=n;i>=1;i--){ 42 maxn2=max(maxn2,a[i]); 43 if(vis2[a[i]]==1){ 44 continue; 45 } 46 if(a[i]<=maxn2){ 47 vis2[a[i]]=1; 48 num2++; 49 } 50 if(num2==maxn2&&num2==n-i+1){ 51 f2[i]=1; 52 } 53 } 54 int ans=0; 55 for(int i=1;i<=n-1;i++){ 56 if(f1[i]==1&&f2[i+1]==1){ 57 ans++; 58 } 59 } 60 printf("%d\n",ans); 61 for(int i=1;i<=n-1;i++){ 62 if(f1[i]==1&&f2[i+1]==1){ 63 cout << i << " " << n-i << endl; 64 } 65 } 66 67 } 68 }
C - Exercising Walk
题意:a,b,c,d分别代表小猫向左,向右,向下,向上,题目中给出初始位置坐标,限定区域内活动,问经过abcd特定步数移动后是否能够不出界限
思路:a的步数和b的步数是可以相互抵消的,一个往左一个往右,只要左右一个格子在限定范围内就可以,c,d也是这样,ab中小的就直接变成0就可以,cd中小的直接变为0,最后比较界限是否满足abcd中不为0的,如果满足就可以在限定范围内移动,否则反之
w掉的/应该注意的:1.看错abcd到底是往哪移动
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 int main(){ 8 int t; 9 scanf("%d",&t); 10 while(t--){ 11 int a,b,c,d; 12 scanf("%d %d %d %d",&a,&b,&c,&d); 13 int x,y,x1,x2,y1,y2; 14 scanf("%d %d %d %d %d %d",&x,&y,&x1,&y1,&x2,&y2); 15 if(abs(x1-x)>0||abs(x2-x)>0){ 16 if(a>=b){ 17 a-=b; 18 b=0; 19 }else{ 20 b-=a; 21 a=0; 22 } 23 } 24 if(abs(y1-y)>0||abs(y2-y)>0){ 25 if(c>=d){ 26 c-=d; 27 d=0; 28 }else{ 29 d-=c; 30 c=0; 31 } 32 } 33 34 int flag=0; 35 if(a>=0&&(x-x1)>=a){ 36 flag++; 37 } 38 if(b>=0&&(x2-x)>=b){ 39 flag++; 40 } 41 if(c>=0&&(y-y1)>=c){ 42 flag++; 43 } 44 if(d>=0&&(y2-y)>=d){ 45 flag++; 46 } 47 48 if(flag==4){ 49 printf("Yes\n"); 50 }else{ 51 printf("No\n"); 52 } 53 } 54 }
D - Composite Coloring
题意:1000以内所有的数可以用11种不同颜色染色就可以,染色要求,两个数如果有公因数就可以染成同一种颜色,给出一组数,输出染色结果就可以
思路:公因数即使是合数分解以后也是有公共的素数,所以找出11个素数来即可,再进行判断两个数是不是有公约数
wa掉的/注意的:1.一开始我是想用更相减损法计算公约数是不是1,再进行染色,不过好像会出问题
2.后来存入了11个素数,很精巧的是找序号的时候,当这个数的因子有这11个素数里面的数时,就把它变成这个素数,方便以后识别,然后标记一下这个素数是存在于这个数组的,然后通过map进行序号标识把素数值指向序号即可
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<cstring> 7 using namespace std; 8 int a[1005],n; 9 int prime[12]={0,2,3,5,7,11,13,17,19,23,29,31}; 10 int main(){ 11 int t; 12 scanf("%d",&t); 13 while(t--){ 14 map<int,int>mp; 15 scanf("%d",&n); 16 int i,j; 17 int b[1005]={0}; 18 19 for(i=1;i<=n;i++){ 20 scanf("%d",&a[i]); 21 for(j=1;j<=11;j++){ 22 if(a[i]%prime[j]==0){ 23 a[i]=prime[j]; 24 b[prime[j]]=1; 25 } 26 } 27 } 28 int cnt=1; 29 for(i=1;i<=11;i++){ 30 if(b[prime[i]]==1){//找序号 31 mp[prime[i]]=cnt; 32 cnt++; 33 } 34 } 35 printf("%d\n",mp.size()); 36 for(i=1;i<=n;i++) { 37 printf("%d ",mp[a[i]]); 38 } 39 printf("\n"); 40 } 41 }
E - K-th Beautiful String
题意:按照字典顺序输出字符串,字符串长度不固定看题目输出,一定的是有两个b,其余的都是a
思路:从左往右的第一个b位置是固定的,当字典序为1时,b在从右往左数第二位,当字典序为2,3时,b在从右往左数第三位……,第二个在从最右边一步步挨近第一个字母b
wa掉的/需要注意的:1.不要复杂的找到到底还剩多少个a,找到b的集体位置在哪就好,剩下的直接限制字符长度直接输出a即可
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 int main(){ 8 int t; 9 scanf("%d",&t); 10 while(t--){ 11 int n,k; 12 scanf("%d %d",&n,&k); 13 int flag=0; 14 int poi=0;//poi所在组数 15 int i=0; 16 for(i=1;i<n;i++){ 17 if(k<=i){ 18 break; 19 } 20 k-=i; 21 } 22 i=n-i; 23 k=n-k+1; 24 for(int j=1;j<=n;j++){ 25 if(j==i||j==k){ 26 printf("b"); 27 }else{ 28 printf("a"); 29 } 30 } 31 printf("\n"); 32 } 33 }
F - Carousel
题意:染色问题,不同的数字不能染成以一种颜色,所给数组是一个环,输出染色结果,限制所用颜色最少
思路:先分类:1.只有一个种类或n=1,那么全涂一种颜色就行了。
2.偶数个元素,全涂1和2相间染色,到一定满足要求且最优
3.奇数个元素(这个时候因为末尾元素可能会和n−1或1号元素颜色相同,所以我们再继续分类)
(1) n和n−1的种类相同,和1随意,那么前面还是1和2相间染色,最后一个元素和n-1同色,这样保证了和1不同色。
(2)n和1种类相同,那么直接1和2相间染色
(3) 值得注意的是和两边种类不同时,为了使答案是2,我们要尽可能让1和n−1号元素的颜色相同
如果前面有重复元素连在一起,那么改变一个重复元素不相间染色,后面相间染色,那就和偶数的情况一样
例子:种类:1 1 2 3 4
相间染色:1 2 1 2 1(此时不满足条件)
改变重复元素:1 1 2 1 2(满足条件)
如果没有上面这种情况,只能新开颜色3,给末尾元素涂上3.
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 const int maxn=2*1e5+9; 8 int t[maxn],q,n,a[maxn],k; 9 void print(int k,int w){ 10 cout<<k<<endl; 11 for(int i=1;i<=w;i++) cout<<a[i]<<" "; 12 } 13 int main(){ 14 scanf("%d",&q); 15 while(q--) 16 { 17 k=1; 18 cin>>n; 19 int flag=0; 20 for(int i=1;i<=n;i++) 21 { 22 cin>>t[i]; 23 if(t[i]!=t[i-1]&&i!=1) flag=1; 24 } 25 if(flag==0||n==1)//只有一种颜色 26 { 27 cout<<1<<endl; 28 for(int i=1;i<=n;i++) cout<<1<<" "; 29 } 30 else 31 { 32 for(int i=1;i<=n;i++) 33 if(i%2==1) a[i]=1; 34 else a[i]=2; 35 if(n%2==0) print(2,n); 36 else 37 { 38 if(t[n]!=t[n-1]&&t[n]!=t[1]) 39 { 40 int P=0; 41 for(int i=2;i<=n-1;i++) 42 if(t[i]==t[i-1]) P++; 43 if(P>=1) 44 { 45 a[1]=1;int num; 46 for(int i=2;i<=n-1;i++) 47 { 48 if(t[i]==t[i-1]) 49 { 50 a[i]=a[i-1],num=i+1; 51 break; 52 } 53 } 54 for(int i=num;i<=n;i++) 55 if(a[i-1]==1) a[i]=2; 56 else a[i]=1; 57 print(2,n); 58 } 59 else 60 { 61 a[n]=3; 62 print(3,n); 63 } 64 } 65 else if(t[n]!=t[n-1]) print(2,n);//和n-1个不相等 66 else if(t[n]!=t[1])//和第一个不相等 67 { 68 a[n]=2; 69 print(2,n); 70 } 71 else print(2,n);//都不相等,怎么都可以 72 } 73 } 74 cout<<endl; 75 } 76 }

浙公网安备 33010602011771号