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 }
View Code

 

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 }
View Code

 

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     }
View Code

 

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 }
View Code

 

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 }
View Code

 

F - Carousel

题意:染色问题,不同的数字不能染成以一种颜色,所给数组是一个环,输出染色结果,限制所用颜色最少

思路:先分类:1.n=1,

2.,12

3.素(n11类)

1 nn11意,那么前面还是1和2相间染色,最后一个元素和n-1同色,这样保证了和1不同色。

2n1,12

3 使21n1

如果前面有重复元素连在一起,那么改变一个重复元素不相间染色,后面相间染色,那就和偶数的情况一样

例子:种类: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 }
View Code

 

posted @ 2020-06-04 22:04  bonel  阅读(166)  评论(0)    收藏  举报