• Codeforces #533 div2 做题记录


    A.

    题解:枚举答案,验证

    代码:

     1 #include<bits/stdc++.h>
     2 #define maxn 1005
     3 using namespace std;
     4 int n;
     5 int a[maxn];
     6 int main()
     7 {
     8     scanf("%d",&n);
     9     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    10     int ans=1,val=100000000;
    11     for(int k=1;k<=100;++k)
    12     {
    13         int t=0;
    14         for(int i=1;i<=n;++i)
    15         {
    16             if(a[i]>k)t+=a[i]-(k+1);
    17             if(a[i]<k)t+=(k-1)-a[i];
    18         }
    19         if(t<val)val=t,ans=k;
    20     }
    21     printf("%d %d
    ",ans,val);
    22     return 0;
    23 }

    B.

    题解:考虑到每个长度为k的串的字母相同,用two-pointers维护出现次数,然后在长度为k字母相同的串结尾位置标记val=1,最后对每种字母DP就行

     1 #include<bits/stdc++.h>
     2 #define maxn 200005
     3 using namespace std;
     4 int n,k;
     5 char s[maxn];
     6 int val[maxn];
     7 int c[30],num;
     8 int dp[maxn];
     9 int main()
    10 {
    11     scanf("%d%d",&n,&k);
    12     scanf("%s",s+1);
    13     for(int l=1;l<=k;++l)
    14     {
    15         int t=s[l]-'a';
    16         if(!c[t])num++;
    17         c[t]++;
    18     }
    19     for(int r=k;r<=n;++r)
    20     {
    21         if(num==1)val[r]=1;
    22         int l=r-k+1;
    23         if(c[s[l]-'a']==1)num--;
    24         c[s[l]-'a']--;
    25         if(r!=n)
    26         {
    27             if(!c[s[r+1]-'a'])num++;
    28             c[s[r+1]-'a']++;
    29         }
    30     }
    31     int ans=0;
    32     for(int p=0;p<26;++p)
    33     {
    34         for(int i=k;i<=n;++i)
    35         {
    36             dp[i]=dp[i-1];
    37             if(s[i]-'a'==p&&dp[i]<dp[i-k]+val[i])dp[i]=dp[i-k]+val[i];
    38         }
    39         ans=max(ans,dp[n]);
    40     }
    41     printf("%d
    ",ans);
    42     return 0;
    43 }

    C.

    题解:简单计数DP,按 mod 3 分类。

     1 #include<bits/stdc++.h>
     2 #define maxn 200005
     3 #define ll long long
     4 using namespace std;
     5 const ll mod = 1000000007;
     6 int n;
     7 ll l,r;
     8 ll val[4];
     9 ll dp[maxn][4];
    10 int main()
    11 {
    12     scanf("%d%I64d%I64d",&n,&l,&r);
    13     ll t=(r-l+1)/3,d=(r-l+1)%3;
    14     if(d==0)val[0]=val[1]=val[2]=t;
    15     if(d==1)
    16     {
    17         val[0]=val[1]=val[2]=t;
    18         int x=(int)(l%3);
    19         val[x]++;
    20     }
    21     if(d==2)
    22     {
    23         val[0]=val[1]=val[2]=t;
    24         int x=(int)(l%3);
    25         int y=(int)((l+1)%3);
    26         val[x]++;val[y]++;
    27     }
    28     dp[0][0]=1;
    29     for(int i=1;i<=n;++i)
    30     {
    31         dp[i][0]=(dp[i-1][0]*val[0]%mod+dp[i-1][1]*val[2]%mod+dp[i-1][2]*val[1]%mod)%mod;
    32         dp[i][1]=(dp[i-1][0]*val[1]%mod+dp[i-1][1]*val[0]%mod+dp[i-1][2]*val[2]%mod)%mod;
    33         dp[i][2]=(dp[i-1][0]*val[2]%mod+dp[i-1][1]*val[1]%mod+dp[i-1][2]*val[0]%mod)%mod;
    34     }
    35     int ans=dp[n][0];
    36     printf("%d
    ",ans);
    37     return 0;
    38 }

    D.

    题解:开p个队列,每次从可扩展点开始bfs就行

      1 #include<bits/stdc++.h>
      2 #define maxn 1005
      3 using namespace std;
      4 int n,m,p;
      5 char a[maxn][maxn];
      6 int s[maxn];
      7 struct node
      8 {
      9     int x,y;
     10     node(){}
     11     node(int X,int Y){x=X;y=Y;}
     12 };
     13 queue<node> q[10];
     14 stack<node> stk;
     15 int dis[maxn][maxn];
     16 int Ans[10];
     17 int main()
     18 {
     19     scanf("%d%d%d",&n,&m,&p);
     20     for(int i=1;i<=p;++i)scanf("%d",&s[i]);
     21     for(int i=1;i<=n;++i)scanf("%s",a[i]+1);
     22     for(int i=1;i<=n;++i)
     23         for(int j=1;j<=m;++j)
     24         {
     25             int k=a[i][j]-'0';
     26             if(1<=k&&k<=p)q[k].push(node(i,j)); 
     27         }
     28     while(1)
     29     {
     30         for(int k=1;k<=p;++k)
     31         {
     32             while(!q[k].empty())
     33             {
     34                 node u=q[k].front();
     35                 q[k].pop();
     36                 int x=u.x,y=u.y;
     37                 if(a[x-1][y]=='.'||a[x+1][y]=='.'||a[x][y-1]=='.'||a[x][y+1]=='.')
     38                 {
     39                     stk.push(u);
     40                     dis[x][y]=0;
     41                 }
     42             }
     43             while(!stk.empty())
     44             {
     45                 q[k].push(stk.top());
     46                 stk.pop(); 
     47             }
     48         }
     49         int flag=0;
     50         for(int k=1;k<=p;++k)if(!q[k].empty())flag=1;
     51         if(!flag)break;
     52         for(int k=1;k<=p;++k)
     53         {
     54             while(!q[k].empty())
     55             {
     56                 node u=q[k].front();q[k].pop();
     57                 int x=u.x,y=u.y;
     58                 if(dis[x][y]==s[k])
     59                 {
     60                     stk.push(u);
     61                     continue;
     62                 }
     63                 if(a[x-1][y]=='.')
     64                 {
     65                     dis[x-1][y]=dis[x][y]+1;
     66                     a[x-1][y]='0'+k;
     67                     q[k].push(node(x-1,y));
     68                 }
     69                 if(a[x+1][y]=='.')
     70                 {
     71                     dis[x+1][y]=dis[x][y]+1;
     72                     a[x+1][y]='0'+k;
     73                     q[k].push(node(x+1,y));
     74                 }
     75                 if(a[x][y-1]=='.')
     76                 {
     77                     dis[x][y-1]=dis[x][y]+1;
     78                     a[x][y-1]='0'+k;
     79                     q[k].push(node(x,y-1));
     80                 }
     81                 if(a[x][y+1]=='.')
     82                 {
     83                     dis[x][y+1]=dis[x][y]+1;
     84                     a[x][y+1]='0'+k;
     85                     q[k].push(node(x,y+1));
     86                 }
     87             }
     88             while(!stk.empty())
     89             {
     90                 node u=stk.top();
     91                 stk.pop();
     92                 q[k].push(u);
     93             }
     94         }
     95     }
     96     for(int i=1;i<=n;++i)
     97         for(int j=1;j<=m;++j)
     98         {
     99             int k=a[i][j]-'0';
    100             if(1<=k&&k<=p)Ans[k]++;
    101         }
    102     for(int i=1;i<=p;++i)printf("%d ",Ans[i]);
    103     return 0; 
    104 }

    E.

    题解:

    考虑这个序列,连续的一堆1是没有意义的,我们可以缩成一个;

    然后就是1 2 2 2 …… 1 2 2 ……这样的形式;

    对于每个1后面缀着的2,我们只能选1个,因此,只要有两个人在某段中共用一个1,那么这两个人就不能同时选;

    这是个最大独立集问题,我们考虑转化成补图的最大团;

    m=40,求最大团有不少方法,这里使用一个写起来简单的方法:随机化

    考虑随机一个排列,然后贪心地选择点加入最大团,做个上千次就很对了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m;
     4 map<string,int> mp;
     5 bool has[42][100005];
     6 int a[42][42];
     7 int p[42];
     8 bool is[42];
     9 int ans,Ans[42];
    10 int main()
    11 {
    12     scanf("%d%d",&n,&m);
    13     int last=0,cnt=0;
    14     for(int i=1;i<=n;++i)
    15     {
    16         int opt;
    17         scanf("%d",&opt);
    18         if(opt==1)++last;
    19         else
    20         {
    21             string s;
    22             cin>>s;
    23             if(!mp.count(s))mp[s]=++cnt;
    24             has[mp[s]][last]=1;
    25         }
    26     }
    27     for(int i=1;i<=m;++i)
    28     {
    29         for(int j=i+1;j<=m;++j)
    30         {
    31             bool yes=1;
    32             for(int k=1;k<=last;++k)if(has[i][k]&&has[j][k])yes=0;
    33             if(yes)a[i][j]=a[j][i]=1;
    34         }
    35     }
    36     for(int i=1;i<=m;++i)p[i]=i;
    37     srand(time(NULL));
    38     for(int t=1;t<=3000;++t)
    39     {
    40         random_shuffle(p+1,p+m+1);
    41         memset(is,0,sizeof(is));
    42         int num=0;
    43         for(int i=1;i<=m;++i)
    44         {
    45             bool ok=1;
    46             for(int j=1;j<i;++j)if(is[p[j]]&&!a[p[i]][p[j]])ok=0;
    47             if(ok)is[p[i]]=1,num++;
    48         }
    49         if(num>ans)
    50         {
    51             ans=0;
    52             for(int i=1;i<=m;++i)if(is[p[i]])Ans[++ans]=p[i];
    53         }
    54     }
    55     printf("%d
    ",ans);
    56     return 0;
    57 }
  • 相关阅读:
    macbook如何清理磁盘中的“容器中的其他宗卷”
    Maven本地仓库与远程仓库配置
    查看MySQL库、表所占磁盘空间大小
    数据库操作
    Mac Mysql初始密码重置
    Vue 性能优化经验总结
    【读书笔记】对象创建摘录
    【读书笔记】 函数柯里化
    js实现仿windows文件按名称排序
    本来想偷懒的今天,想了想,还是写一篇吧,前端登录界面,用的BOOTSTRAP
  • 原文地址:https://www.cnblogs.com/uuzlove/p/10296985.html
Copyright © 2020-2023  润新知