Codeforces Round #545 (Div. 2) ABCD 题解

题目链接

A. Sushi for Two

分析

模拟题,只需要模拟找出连续最长的111222或222111这种数段即可.

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <string>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 #include <map> 
12 const int INF=0x3f3f3f3f;
13 using namespace std;
14 
15 int s[100000];
16 
17 int main()
18 {
19     int n;
20     cin>>n;
21     for(int i=0;i<n;i++) scanf("%d",&s[i]);
22     int k=0;
23     int ans=0,a=0,b=0;
24     while(k<n)
25     {
26         while(s[k]==1&&k<n) a++,k++;
27         if(a<=b) ans=max(ans,2*a);
28         else ans=max(ans,2*b);
29         b=0;
30         while(s[k]==2&&k<n) b++,k++;
31         if(b<=a) ans=max(ans,2*b);
32         else ans=max(ans,2*a);
33         a=0;
34     }
35     cout<<ans<<endl;
36     return 0;
37 }
View Code

 

B. Circus

分析

这题需要找出题目中的数学关系,先把人分成4种(0,0)(1,0)(0,1)(1,1),人数分别为a0,b0,c0,d0,总人数为n,假设第一场4种人分别选了a,b,c,d个,依题意有a+b+c+d=n/2,b+d=c0-c+d0-d,这个方程组有两个方程4个变量,即有两个未知量,分别枚举其中两个未知量,来确定另外两个未知量,只要保证算出来的a,b,c,d合法即可.(下面代码思路相同不过设置的变量不同,仅供参考)

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <string>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 #include <map> 
12 const int INF=0x3f3f3f3f;
13 using namespace std;
14 
15 int a[5000],b[5000],c[5000],d[5000];
16 char fir[5000],sec[5000];
17 
18 int main()
19 {
20     int na=0,nb=0,nc=0,nd=0;
21     int n;
22     cin>>n;
23     getchar();
24     for(int i=0;i<n;i++) scanf("%c",&fir[i]);
25     getchar();
26     for(int i=0;i<n;i++)
27     {
28         scanf("%c",&sec[i]);
29         if(fir[i]=='0'&&sec[i]=='0') a[na++]=i+1;
30         if(fir[i]=='0'&&sec[i]=='1') b[nb++]=i+1;
31         if(fir[i]=='1'&&sec[i]=='0') c[nc++]=i+1;
32         if(fir[i]=='1'&&sec[i]=='1') d[nd++]=i+1;
33     }
34 
35     int i=-1,j=-1,k=-1,l=-1; 
36     for(i=0;i<=na;i++)
37     {
38         int s=0;
39         for(j=0;j<=nb;j++)
40          {
41             k=n-2*i-nb-nd-j;
42             l=nb+nd-n/2+i;
43             if(nc>=k&&k>=0&&l>=0&&nd>=l)
44             {
45                 s=1;
46                 break;
47             }
48         }
49         if(s) break;
50     }
51 
52     if(i<=na&&j<=nb)
53     {
54         for(int q=0;q<i;q++) cout<<a[q]<<' ';
55         for(int q=0;q<j;q++) cout<<b[q]<<' ';
56         for(int q=0;q<k;q++) cout<<c[q]<<' ';
57         for(int q=0;q<l;q++) cout<<d[q]<<' ';
58         cout<<endl;
59     }
60     else cout<<-1<<endl;
61     return 0;
62 }
View Code

 

C. Skyscrapers

分析

这道题读懂题意后最关键的是离散化操作,这个操作会了码一下细节基本就过了.

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <string>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set> 
13 const int INF=0x3f3f3f3f;
14 using namespace std;
15 
16 typedef pair<int,int> P;
17 int row[1000][1000];
18 int r[1000];
19 int column[1000][1000];
20 int c[1000];
21 int mapp[1000][1000];
22 vector<int> v;
23 
24 int main()
25 {
26     int n,m;
27     cin>>n>>m;
28     for(int i=0;i<n;i++)
29     for(int j=0;j<m;j++)
30     scanf("%d",&mapp[i][j]);
31     for(int i=0;i<n;i++)
32     {
33         
34         for(int j=0;j<m;j++) v.push_back(mapp[i][j]);
35         sort(v.begin(),v.end());
36         vector<int>::iterator e=unique(v.begin(),v.end());
37         r[i]=e-v.begin();
38         for(int j=0;j<m;j++) row[i][j]=lower_bound(v.begin(),e,mapp[i][j])-v.begin()+1;
39         v.clear();
40     }
41     for(int j=0;j<m;j++)
42     {
43         
44         for(int i=0;i<n;i++) v.push_back(mapp[i][j]);
45         sort(v.begin(),v.end());
46         vector<int>::iterator e=unique(v.begin(),v.end());
47         c[j]=e-v.begin();
48         for(int i=0;i<n;i++) column[i][j]=lower_bound(v.begin(),e,mapp[i][j])-v.begin()+1;
49         v.clear();
50     }
51 
52 /*    for(int i=0;i<n;i++)
53     {
54     for(int j=0;j<m;j++)
55     printf("r=%d,c=%d ",row[i][j],column[i][j]);
56     cout<<endl;
57     }
58     for(int i=0;i<n;i++) printf("r[%d]=%d\n",i,r[i]);
59     for(int j=0;j<m;j++) printf("c[%d]=%d\n",j,c[j]);
60 */ 
61     for(int i=0;i<n;i++)
62     {
63         for(int j=0;j<m;j++)
64         {
65              int a=row[i][j],b=column[i][j],ans=INF;
66              if(a>=b) ans=max(r[i],c[j]+a-b);
67              else ans=max(r[i]+b-a,c[j]);
68              cout<<ans<<' ';
69         }
70         cout<<endl;
71     }
72     return 0;
73 }
View Code

 

D. Camp Schedule

分析

kmp算法的题,只需要把第一个字符串拆成1和0,再求出第二个字符串的最小循环节,然后不断按最小循环节顺序输出1,0直到拆分的1或0不够用为止,再把剩下的0或1输出完即可.

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <utility>
 7 #include <vector>
 8 #include <string>
 9 #include <queue>
10 #include <stack>
11 #include <map> 
12 const int INF=0x3f3f3f3f;
13 using namespace std;
14 
15 char a[600000];
16 int b[600000];
17 
18 void kmp(int cnt)
19 {
20     int i=0;
21     int k=-1;
22     b[0]=-1;
23     while(i<cnt)
24     {
25         
26         if(k==-1||a[i]==a[k])
27         {
28             if(a[++i]==a[++k]) b[i]=b[k]; 
29             else b[i]=k;
30         }
31         else k=b[k];
32     }
33     return ;
34 }
35 
36 int main()
37 {
38     char x;
39     //��ֵ�һ������ 
40     int a0=0,a1=0;
41     while(scanf("%c",&x)&&x!='\n')
42     {
43         if(x=='0') a0++;
44         else a1++;
45     }
46     
47     int k=0; 
48     while(scanf("%c",&x)&&x!='\n') a[k++]=x;
49     kmp(k);
50     int l=k-b[k];
51     
52     
53     //����Сѭ���ڲ��Ϲ�������,ֱ����һ�����е�0��1������,�ٰ�ʣ�µ�0��1ȫ��������� 
54     int s=0;
55     while(1)
56     {
57         if(s) break;
58         for(int i=0;i<l;i++)
59         {
60             if(a[i]=='0'&&a0) printf("0"),a0--;
61             else if(a[i]=='1'&&a1) printf("1"),a1--;
62             else 
63             {
64                 s=1;
65                 break;
66             }
67         }
68     }
69     if(a0) 
70     {
71         for(int i=0;i<a0;i++) printf("0");
72         cout<<endl;
73     }
74     else if(a1)
75     {
76         for(int i=0;i<a1;i++) printf("1");
77         cout<<endl;
78     }
79     else cout<<endl;
80     return 0;
81 }
View Code

 

转载于:https://www.cnblogs.com/VBEL/p/10623920.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值