Codeforces Round #531 (Div. 3)

Posted lqllulu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #531 (Div. 3)相关的知识,希望对你有一定的参考价值。

A. Integer Sequence Dividing

技术图片
 1 #include <cstdio>
 2 
 3 using namespace std;
 4 int n;
 5 
 6 int main(){
 7     scanf("%d",&n);
 8     if((n+1)%2==0){
 9         n=(n+1)/2;
10         if(n%2==0){
11             printf("0
");
12         }else{
13             printf("1
");
14         }
15     }else{
16         n=n/2;
17         if(n%2==0){
18             printf("0
");
19         }else{
20             printf("1
");
21         }
22     }
23 
24 return 0;
25 }
View Code

B. Array K-Coloring

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <vector>
 6 
 7 using namespace std;
 8 const int maxn=5000+100;
 9 int a[maxn],num[maxn];
10 vector<int>pos[maxn];
11 int ans[maxn],now[maxn][maxn];
12 
13 int n,k,ty;
14 int main(){
15     scanf("%d%d",&n,&k);
16     int flag=1;
17     for(int i=1;i<=n;i++){
18         scanf("%d",&a[i]);
19         if(num[a[i]]==0){
20             ty++;
21             num[a[i]]=ty;
22         }
23         pos[a[i]].push_back(i);
24         if(pos[a[i]].size()>k){
25             flag=0;
26             break;
27         }
28     }
29 
30     if(n<k){
31         flag=0;
32     }
33     if(!flag){
34         printf("NO
");
35         return 0;
36     }
37     for(int i=1;i<=k;i++){
38         ans[i]=i;
39         now[num[a[i]]][i]=1;
40     }
41     for(int i=k+1;i<=n;i++){
42         for(int j=1;j<=k;j++){
43             if(!now[num[a[i]]][j]){
44                 now[num[a[i]]][j]=1;
45                 ans[i]=j;
46                 break;
47             }
48         }
49     }
50     printf("YES
");
51     for(int i=1;i<=n;i++){
52         printf("%d ",ans[i]);
53     }
54 
55 return 0;
56 }
View Code

C. Doors Breaking and Repairing

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 const int maxn=100+10;
 8 int n,x,y;
 9 int a[maxn];
10 int main(){
11     scanf("%d%d%d",&n,&x,&y);
12     if(x>y){
13         printf("%d
",n);
14         return 0;
15     }
16     int num=0;
17     for(int i=1;i<=n;i++){
18         scanf("%d",&a[i]);
19         if(a[i]<=x)
20             num++;
21     }
22     int ans=num/2;
23     if(num%2)ans++;
24     printf("%d
",ans);
25 return 0;
26 }
View Code

D. Balanced Ternary String

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 const int maxn=3e5+100;
 8 char s[maxn];
 9 int n;
10 int num[3];
11 int main(){
12     scanf("%d",&n);
13     scanf("%s",s);
14     for(int i=0;i<n;i++){
15         int a=s[i]-0;
16         num[a]++;
17     }
18     int res=n/3;
19     for(int i=0;i<n;i++){
20         int a=s[i]-0;
21         if(num[a]>res){
22             for(int j=0;j<a;j++){
23                 if(num[j]<res){
24                     s[i]=j+0;
25                     num[j]++;
26                     num[a]--;
27                     break;
28                 }
29             }
30         }
31     }
32     for(int i=n-1;i>=0;i--){
33         int a=s[i]-0;
34         if(num[a]>res){
35             for(int j=2;j>a;j--){
36                 if(num[j]<res){
37                     s[i]=j+0;
38                     num[j]++;
39                     num[a]--;
40                     break;
41                 }
42             }
43         }
44     }
45     printf("%s
",s);
46 return 0;
47 }
View Code

E. Monotonic Renumeration

显然相同的数字一段必须一样。

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <vector>
 6 #include <map>
 7 
 8 using namespace std;
 9 typedef long long LL;
10 const int mod=998244353;
11 const int maxn=2e5+10;
12 map<int,int>mp;
13 int a[maxn];
14 int n;
15 int main(){
16     scanf("%d",&n);
17 
18     for(int i=1;i<=n;i++){
19         scanf("%d",&a[i]);
20         mp[a[i]]=i;
21     }
22     int right=1;
23     LL ans=1;
24     for(int i=1;i<=n;i++){
25         if(right>=i)
26             right=max(right,mp[a[i]]);
27         else{
28             ans=ans*2%mod;
29             right=max(right,mp[a[i]]);
30         }
31     }
32     printf("%I64d
",ans);
33 return 0;
34 }
View Code

F. Elongated Matrix

题意

给出一个n*m的矩阵a,每个格子都有一个整数。你可以任意的改变行的顺序,当你确定了一种行的顺序以后,你需要通过下面的方式遍历整个矩阵:首先访问第一列从上到下每个格子,然后第二列。。在遍历的过程中,你要把遍历走过的数字写下了形成一个序列,这个序列为s1,s2,...,snm.
当对于每个i都满足|si-si+1|>=k的时候合法。请找出存在合法序列的最大的整数k。

其中n<=16,m<=10^4.

题解:

个人感觉这是一个好题。

因为行的顺序可以随便换,所以从 第i行可以走到除了i以外的任意行。那么以行为结点,枚举第一行和最后一行,然后在中间的点之间连边,那么就是求从第一行到最后一行,每一行恰好经过一次,路径上最小权值最大。现在就变成了一个哈密顿路径问题。可以通过状态压缩解决。

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <cmath>
 6 
 7 using namespace std;
 8 const int INF=2147000000;
 9 const int maxn=17;
10 const int maxm=1e4+10;
11 int a[maxn][maxm],Min[maxn][maxn];
12 int n,m;
13 int dp[1<<maxn][maxn];
14 
15 int solve(int h,int d,int S,int u){
16     int SS=(1<<n)-1;
17     SS^=(1<<(h-1));
18     SS^=(1<<(d-1));
19     if(SS==S)return Min[u][d];
20 
21     if(dp[S][u]!=-1){
22         return dp[S][u];
23     }
24     dp[S][u]=0;
25     for(int i=1;i<=n;i++){
26         if(i!=h&&i!=d&&i!=u){
27             if(S&(1<<(i-1)))continue;
28             dp[S][u]=max(dp[S][u],min(solve(h,d,S|(1<<(i-1)),i),Min[u][i]));
29         }
30     }
31    // printf("%d %d %d
",S,u,dp[S][u]);
32     return dp[S][u];
33 }
34 
35 int main(){
36     scanf("%d%d",&n,&m);
37     for(int i=1;i<=n;i++){
38         for(int j=1;j<=m;j++){
39             scanf("%d",&a[i][j]);
40         }
41     }
42     if(n==1){
43         int res=INF;
44         for(int i=1;i<m;i++){
45             res=min(res,abs(a[1][i]-a[1][i+1]));
46         }
47         printf("%d
",res);
48         return 0;
49     }
50     for(int i=1;i<=n;i++){
51         for(int j=1;j<=n;j++){
52             if(i==j)continue;
53             Min[i][j]=INF;
54             for(int k=1;k<=m;k++){
55                 Min[i][j]=min(Min[i][j],abs(a[i][k]-a[j][k]));
56             }
57         }
58     }
59 
60     int ans=0;
61 
62     for(int i=1;i<=n;i++){
63         for(int j=1;j<=n;j++){
64             if(i==j)continue;
65             int res=INF;
66             for(int k=1;k<m;k++){
67                 res=min(res,abs(a[i][k]-a[j][k+1]));
68             }
69             if(m==1)res=INF;
70             memset(dp,-1,sizeof(dp));
71             res=min(res,solve(i,j,0,i));
72             ans=max(ans,res);
73         }
74     }
75     printf("%d
",ans);
76 return 0;
77 }
View Code

 

以上是关于Codeforces Round #531 (Div. 3)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #531 (Div. 3)

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces #531.div3

Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)

Codeforces Global Round 19