Codeforces Round #704 (Div. 2)

A. Three swimmers

题意:第一个人跳水是每隔a分钟去一次,第二个人跳水是每隔b分钟,第三个人跳水是每隔c分钟,一个人准备在p分钟的 时候去跳水,问需要最少等待多长时间才能轮到前三个人

思路:数学公式进行找,从头到尾挨个人找就行不用混着,混着也没有办法下手

 

当时:1)当时想着从头开始然后一直用while循环,根本想不到用数学公式,也没有想到是分开来计算的

代码:

 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         long long int p,a,b,c;
12         long long int cc=1e18;
13         scanf("%lld %lld %lld %lld",&p,&a,&b,&c);
14         long long int aa=a,bb=b,pp=p,t=c;
15         long long int a1,b1,c1;
16         if(p%a!=0){
17             a1=((p/a)+1)*a-p;
18         }else{
19             a1=0;
20         }
21         if(p%b!=0){
22             b1=((p/b)+1)*b-p;
23         }else{
24             b1=0;
25         }
26         if(p%c!=0){
27             c1=((p/c)+1)*c-p;
28         }else{
29             c1=0;
30         }
31         cc=min(cc,a1);
32         cc=min(cc,b1);
33         cc=min(cc,c1);
34  
35         printf("%lld\n",cc);
36     }
37 }
View Code

B. Card Deck

题意:就是给定一组数列,然后这是一摞牌从最底下往上的顺序,然后进行选牌,让最大在下面,保证数值最大

 

思路:就是直接从后往前把最大的选出来就行了,其实也是暴力循环找,从后往前,因为数字是从1-n标记的,第一个就是找n,把n和它之后的数组进行输出并标记一下,然后再通过标记找下一个最大值

代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std;
 7 const int maxx=1e5+10;
 8 int main(){
 9     int t;
10     scanf("%d",&t);
11     while(t--){
12         int n;
13         int a[maxx],b[maxx]={0};
14         scanf("%d",&n);
15         for(int i=0;i<n;i++){
16             scanf("%d",&a[i]);
17         }
18         int t=n,now=n-1;
19         for(int i=n-1;i>=0;i--){
20             if(a[i]==t){
21                 for(int j=i;j<=now;j++){
22                     printf("%d ",a[j]);
23                     b[a[j]]=1;
24                 }
25                 now=i-1;
26                 for(int j=t;j>0;j--){
27                     if(b[j]==0){
28                         t=j;
29                         break;
30                     }
31                 }
32             }
33         }
34         printf("\n");
35     }
36 }
View Code

C. Maximum width

 题意:两个数组,第二个数组包含在第一个里面,问其宽度最大是多少

                  

 思路:最大肯定是前面的在最左边,后面的在最右边,然后开两个数组,一个记录第二个数组,每一个字符在第一个字符串中最左边的位置,一个记录在最右边的位置,然后通过记录找到最大最小的差值是多少

 

记:1)思考极端情况,分出最左最右;2)分别进行计算,尤其是很多形式一样的思路和公式之类的东西;3)找对应位置最左最右的时候,应该学习一下这中想法,最开始把它想象成一对一的那种,所以如果是一对一就应该每次减一,然后在这个基础上进行加加减减的变化找到对应位置

代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std;
 7 const int maxx=2e5+10;
 8 int main(){
 9     int n,m;
10     scanf("%d %d",&n,&m);
11     char a[maxx],b[maxx];
12     getchar();
13     for(int i=1;i<=n;i++){
14         scanf("%c",&a[i]);
15     }
16     getchar();
17     for(int i=1;i<=m;i++){
18         scanf("%c",&b[i]);
19     }
20     int l[maxx],r[maxx];
21     r[m+1]=n+1;
22     for(int i=m;i>0;i--){
23         r[i]=r[i+1]-1;
24         while(a[r[i]]!=b[i]){
25             r[i]--;
26         }
27     }
28    /* printf("%s\n",a);
29     printf("%s\n",b);*/
30     l[0]=0;
31     for(int i=1;i<=m;i++){
32         l[i]=l[i-1]+1;
33         while(a[l[i]]!=b[i]){
34             l[i]++;
35         }
36     }
37   /*  for(int i=0;i<=m+1;i++){
38         printf("%d ",l[i]);
39     }
40     printf("\n");
41     for(int i=0;i<=m+1;i++){
42         printf("%d ",r[i]);
43     }
44     printf("\n");*/
45     int maxn=0;
46     for(int i=1;i<m;i++){
47         maxn=max(r[i+1]-l[i],maxn);
48     }
49     printf("%d\n",maxn);
50 }
View Code

 

这一套题:要想着很多东西不要混着,混着算可能很麻烦,要分开考虑和计算

posted @ 2021-03-02 16:33  bonel  阅读(63)  评论(0)    收藏  举报