CodeCraft-20 (div 2) 做题记录

A.

把所有都放到1号上就行了

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 int T,n,m;
 5 int main()
 6 {
 7     scanf("%d",&T);
 8     while(T--)
 9     {
10         scanf("%d%d",&n,&m);
11         int s=0;
12         for(int x,i=1;i<=n;++i)scanf("%d",&x),s+=x;
13         printf("%d\n",min(m,s));
14     }
15 }
View Code

 

B.

找规律,长度为k的翻转是从k开始的一个后缀拼上剩下的前缀

这个前缀可能是正着的可能是反着的,发现和n,k的奇偶性有关

 1 #include<bits/stdc++.h>
 2 #define maxn 5005
 3 using namespace std;
 4 int T,n;
 5 char str[maxn];
 6 pair<string,int> s[maxn];
 7 int main()
 8 {
 9     scanf("%d",&T);
10     while(T--)
11     {
12         memset(str,0,sizeof(str));
13         scanf("%d",&n);
14         scanf("%s",str+1);
15         for(int i=1;i<=n;++i)
16         {
17             string tmp;
18             for(int j=i;j<=n;++j)tmp.push_back(str[j]);
19             if((n&1)==(i&1))for(int j=i-1;j>=1;--j)tmp.push_back(str[j]);
20             else for(int j=1;j<i;++j)tmp.push_back(str[j]);
21             s[i]=make_pair(tmp,i);
22         }
23         sort(s+1,s+n+1);
24         for(int i=1;i<=n;++i)str[i]=s[1].first[i-1];
25         printf("%s\n",str+1);
26         printf("%d\n",s[1].second);
27     }
28 }
View Code

 

C.

如果\(a_0,b_0\)都不为0,那么乘积就不为$0$

否则找到最小的\(a_i,b_j  \neq 0\)就行了

 1 #include<bits/stdc++.h>
 2 #define maxn 1000005
 3 using namespace std;
 4 int n,m,p;
 5 int a[maxn],b[maxn];
 6 int main()
 7 {
 8     scanf("%d%d%d",&n,&m,&p);
 9     for(int i=0;i<n;++i)scanf("%d",&a[i]),a[i]%=p;
10     for(int i=0;i<m;++i)scanf("%d",&b[i]),b[i]%=p;
11     int i=0,j=0;
12     while(1)
13     {
14         if(a[i]!=0&&b[j]!=0)
15         {
16             printf("%d\n",i+j);
17             break;
18         }
19         if(!a[i])i++;
20         if(!b[j])j++;
21     }
22 }
View Code

 

D.

考虑每种东西都是一个连通块

不是\((-1,-1)\)的话,我们bfs出来这个连通块就行了,反着定向回去

是\((-1,-1)\)的话,如果一个格子显然不合法;否则一定有相邻两个格子,我们构造在这两个格子来回走,其他格子指向这两个格子就行了

 1 #include<bits/stdc++.h>
 2 #define maxn 1005
 3 using namespace std;
 4 int n;
 5 int bx[maxn][maxn],by[maxn][maxn];
 6 char Ans[maxn][maxn];
 7 bool vis[maxn][maxn];
 8 void bfs(int sx,int sy)
 9 {
10     queue< pair<int,int> > q;
11     Ans[sx][sy]='X';
12     q.push(make_pair(sx,sy));
13     vis[sx][sy]=1;
14     while(!q.empty())
15     {
16         pair<int,int> u=q.front();q.pop();
17         int x=u.first,y=u.second;
18         if(bx[x-1][y]==sx&&by[x-1][y]==sy&&!vis[x-1][y])Ans[x-1][y]='D',vis[x-1][y]=1,q.push(make_pair(x-1,y));
19         if(bx[x+1][y]==sx&&by[x+1][y]==sy&&!vis[x+1][y])Ans[x+1][y]='U',vis[x+1][y]=1,q.push(make_pair(x+1,y));
20         if(bx[x][y-1]==sx&&by[x][y-1]==sy&&!vis[x][y-1])Ans[x][y-1]='R',vis[x][y-1]=1,q.push(make_pair(x,y-1));
21         if(bx[x][y+1]==sx&&by[x][y+1]==sy&&!vis[x][y+1])Ans[x][y+1]='L',vis[x][y+1]=1,q.push(make_pair(x,y+1));
22     }
23 }
24 void dfs(int x,int y)
25 {
26     vis[x][y]=1;
27     if(bx[x-1][y]==-1&&!vis[x-1][y])Ans[x-1][y]='D',dfs(x-1,y);
28     if(bx[x+1][y]==-1&&!vis[x+1][y])Ans[x+1][y]='U',dfs(x+1,y);
29     if(bx[x][y-1]==-1&&!vis[x][y-1])Ans[x][y-1]='R',dfs(x,y-1);
30     if(bx[x][y+1]==-1&&!vis[x][y+1])Ans[x][y+1]='L',dfs(x,y+1);
31 }
32 int main()
33 {
34     scanf("%d",&n);
35     for(int i=1;i<=n;++i)
36         for(int j=1;j<=n;++j)scanf("%d%d",&bx[i][j],&by[i][j]);
37     for(int i=1;i<=n;++i)
38         for(int j=1;j<=n;++j)if(bx[i][j]==i&&by[i][j]==j)
39         {
40             bfs(i,j);
41         }
42     for(int i=1;i<=n;++i)
43         for(int j=1;j<=n;++j)if(bx[i][j]==-1&&!vis[i][j])
44         {
45             if(bx[i-1][j]!=-1&&bx[i+1][j]!=-1&&bx[i][j-1]!=-1&&bx[i][j+1]!=-1)continue;
46             if(bx[i-1][j]==-1)Ans[i][j]='U',dfs(i,j);
47             else if(bx[i+1][j]==-1)Ans[i][j]='D',dfs(i,j);
48             else if(bx[i][j-1]==-1)Ans[i][j]='L',dfs(i,j);
49             else if(bx[i][j+1]==-1)Ans[i][j]='R',dfs(i,j);
50         }
51     bool yes=1;
52     for(int i=1;i<=n;++i)
53         for(int j=1;j<=n;++j)if(Ans[i][j]<'A'||Ans[i][j]>'Z')yes=0;
54     if(!yes)puts("INVALID");
55     else
56     {
57         puts("VALID");
58         for(int i=1;i<=n;++i)printf("%s\n",Ans[i]+1);
59     }
60 }
View Code

 

E.

显然\(a\)肯定是选从大到小的前\(p+k\)个里的

那么我们对\(a\)排序,统计前\(k\)个作为基础答案

考虑DP,\(dp[i][S]\)表示选到第\(i\)个状态为\(S\)的答案

假设\(|S|=t\),那么\(i \leq t+k\)的话必须替换一个\(a_{t+k+1}\)进来,否则直接加入就行了

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define maxn 100005
 4 using namespace std;
 5 int n,p,k;
 6 struct Node
 7 {
 8     int val;
 9     int s[9];
10 }a[maxn];
11 bool cmp(Node A,Node B){return A.val>B.val;}
12 ll dp[maxn][130];
13 int main()
14 {
15     scanf("%d%d%d",&n,&p,&k);
16     for(int i=1;i<=n;++i)scanf("%d",&a[i].val);
17     for(int i=1;i<=n;++i)
18         for(int j=0;j<p;++j)scanf("%d",&a[i].s[j]);
19     sort(a+1,a+n+1,cmp);
20     ll sum=0; 
21     for(int i=1;i<=k;++i)sum+=a[i].val;
22     dp[0][0]=sum;
23     for(int i=1;i<=n;++i)
24     {
25         for(int S=0;S<(1<<p);++S)
26         {
27             dp[i][S]=max(dp[i][S],dp[i-1][S]);
28             int num=0;
29             for(int j=0;j<p;++j)if(S&(1<<j))num++;
30             for(int j=0;j<p;++j)if(!(S&(1<<j)))
31             {
32                 if(i<=k+num)dp[i][S|(1<<j)]=max(dp[i][S|(1<<j)],dp[i-1][S]-a[i].val+a[k+num+1].val+a[i].s[j]);
33                 else dp[i][S|(1<<j)]=max(dp[i][S|(1<<j)],dp[i-1][S]+a[i].s[j]);
34             }
35         }
36     }
37     ll ans=0;
38     for(int S=0;S<(1<<p);++S)ans=max(ans,dp[n][S]);
39     cout<<ans<<endl;
40 }
View Code

 

posted @ 2020-03-05 17:25  幽蝶  阅读(273)  评论(1编辑  收藏  举报