• Codeforces Round #533 (Div. 2)


    C:

    题意:

    有n个整数ai,数列a有两个神奇的性质。1.所有的整数都在[l,r]范围内。2.这n个数的和能被3整除。现在给出l和r,和个数n,问你有多少种方法构造出数列a,方案数mod1e9+7.

    题解:

    一个数被3除只有三种可能。1.整除,2.余1,2.余2.

    然后我们再想这个问题,[l,r]区间内,能被3整除的数有多少?a0=r/3-l/3。余1/2的数有多少?a1/2=((r-l+1)-a0)/2.(这里具体余1和余2不重要,想想为什么)

    我们设f[i][j]为前i个数,和除3余j的方案数。怎么转移呢。

    f[i][0]=f[i-1][1]*a2+f[i-1][2]*a1+f[i-1][0]*a0.

    f[i][1]=f[i-1][0]*a1+f[i-1][1]*a0+f[i-1][2]*a2.

    f[i][2]=f[i-1][0]*a2+f[i-1][1]*a1+f[i-1][2]*a0.

     1 #include<stdio.h>
     2 #include<iostream>
     3 using namespace std;
     4 
     5 long long dp[200005][3];
     6 const long long mod=1000000007;
     7 int main(){
     8     int n,l,r;
     9     cin>>n>>l>>r;
    10     long long a0,a1,a2;
    11     long long sum=r-l+1;
    12     a0=r/3-(l-1)/3;
    13     sum-=a0;
    14     a1=sum/2;
    15     a2=sum-a1 ;
    16     dp[1][0]=a0;
    17     dp[1][1]=a1;
    18     dp[1][2]=a2;
    19     for(int i=2;i<=n;i++)
    20     {
    21         dp[i][0]=(dp[i-1][1]*a2+dp[i-1][0]*a0+dp[i-1][2]*a1)%mod;
    22         dp[i][1]=(dp[i-1][1]*a0+dp[i-1][0]*a1+dp[i-1][2]*a2)%mod;
    23         dp[i][2]=(dp[i-1][1]*a1+dp[i-1][0]*a2+dp[i-1][2]*a0)%mod;
    24     }
    25     printf("%I64d
    ",dp[n][0]);
    26 
    27 }
    View Code

    D.题意

    kilani正在和朋友们玩一个游戏,这个游戏在一个n*m的网格上,每个格子要么是空白,要么是已经被占领,每个玩家有一个或者多个城堡。每个玩家轮流进行游戏。对于玩家i,他可以从一个已有的城堡向一个空白的格子扩建一个城堡,如果这个空白的格子和它的曼哈顿距离不超过s[i]。

    求游戏结束后每个玩家占领的格子数量。

    题解:

    一个多源bfs。具体可以看代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <queue>
     6 
     7 #define pir pair<int,int>
     8 #define mkp make_pair
     9 using namespace std;
    10 const int maxn=1000+10;
    11 const int dx[]={0,0,1,-1};
    12 const int dy[]={1,-1,0,0};
    13 
    14 int n,m,p;
    15 int a[10],ans[10];
    16 char G[maxn][maxn];
    17 int vis[maxn][maxn];
    18 struct Node{
    19     int x,y,p;
    20 };
    21 int main(){
    22     scanf("%d%d%d",&n,&m,&p);
    23     for(int i=1;i<=p;i++){
    24         scanf("%d",&a[i]);
    25     }
    26     queue<pir>q;
    27     for(int i=1;i<=n;i++){
    28         for(int j=1;j<=m;j++){
    29             scanf(" %c",&G[i][j]);
    30         }
    31     }
    32     for(int k=1;k<=p;k++){
    33         for(int i=1;i<=n;i++){
    34             for(int j=1;j<=m;j++){
    35               // scanf(" %c",&G[i][j]);
    36                if(G[i][j]!='.'&&G[i][j]!='#'&&G[i][j]-'0'==k){
    37                     vis[i][j]=k;
    38                     q.push(mkp(i,j));
    39                }
    40             }
    41         }
    42     }
    43 
    44 
    45     while(!q.empty()){
    46         pir u=q.front();q.pop();
    47         int x=u.first,y=u.second;
    48         int num=vis[x][y];
    49         queue<Node>q2;
    50         q2.push({x,y,a[num]});
    51         while(!q.empty()){
    52             pir u1=q.front();
    53             if(vis[u1.first][u1.second]==num){
    54                 q.pop();
    55                 q2.push({u1.first,u1.second,a[num]});
    56             }else{
    57                 break;
    58             }
    59         }
    60 
    61         while(!q2.empty()){
    62             Node u1=q2.front();q2.pop();
    63             if(u1.p<=0)continue;
    64             for(int k=0;k<4;k++){
    65                 int nx=u1.x+dx[k];
    66                 int ny=u1.y+dy[k];
    67                 if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&G[nx][ny]=='.'&&vis[nx][ny]==0){
    68                     vis[nx][ny]=num;
    69                     q2.push({nx,ny,u1.p-1});
    70                     q.push(mkp(nx,ny));
    71                 }
    72             }
    73         }
    74 
    75     }
    76 
    77     for(int i=1;i<=n;i++){
    78         for(int j=1;j<=m;j++){
    79             if(vis[i][j]){
    80                 ans[vis[i][j]]++;
    81                 //printf("%d ",vis[i][j]);
    82             }
    83         }
    84         //printf("
    ");
    85     }
    86 
    87     for(int i=1;i<=p;i++){
    88         printf("%d ",ans[i]);
    89     }
    90 return 0;
    91 }
    View Code

    E. Helping Hiasat

    题意:

    Hiasat有一个社交账号,当他的朋友们每次来看他社交首页的时候,如果他首页的名字是这个朋友的名字,他朋友就会很开心。给出一个序列代表可以修改名字的时间和朋友们来访问的顺序,问如何修改才能让开心的朋友们最多。

    题解:

    显然在两次修改之间的所有访问,只能满足一次。那么其实很显然,将这些点之间连边,然后求图的最大独立集。然后最大独立集怎么求?求补图中的最大团。最大团怎么求?套板子啊!!

     1 include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 55;
     4 bool mp[maxn][maxn];
     5 int num[maxn], group[maxn], now[maxn];
     6 int n, m, ans;
     7 bool dfs(int u, int cnt)
     8 {
     9     int i, j;
    10     for(i = u+1; i <= n; ++i)
    11     {
    12         if(num[i]+cnt <= ans) return false;    //��֦3
    13         if(mp[u][i])
    14         {
    15             for(j = 0; j < cnt; ++j)
    16             if(!mp[i][now[j]]) break;
    17             if(j == cnt)    //�Ż�
    18             {
    19                 now[cnt] = i;
    20                 if(dfs(i, cnt+1)) return true;
    21             }
    22         }
    23     }
    24     if(cnt > ans)
    25     {
    26         for(i = 0; i < cnt; ++i)
    27         group[i] = now[i];
    28         ans = cnt;
    29         return true;
    30     }
    31     return false;
    32 }
    33 
    34 int MaximumClique()
    35 {
    36     ans = -1;
    37     for(int i = n; i >= 1; --i)
    38     {
    39         now[0] = i;
    40         dfs(i, 1);
    41         num[i] = ans;
    42     }
    43     return ans;
    44 }
    45 map<string,int>Name;
    46 int name_num;
    47 int N,M;
    48 int G[maxn][maxn];
    49 
    50 int main()
    51 {
    52     scanf("%d%d",&N,&M);
    53     vector<int>per;
    54     set<int>S;
    55     for(int i=1;i<=N;i++){
    56         int type;
    57         scanf("%d",&type);
    58         if(type==1){
    59             per.clear();
    60             S.clear();
    61         }else{
    62             string name;
    63             cin>>name;
    64             if(!Name.count(name)){
    65                 Name[name]=++name_num;
    66             }
    67             if(!S.count(Name[name])){
    68                 S.insert(Name[name]);
    69                 for(int i=0;i<per.size();i++){
    70                     int u=per[i];
    71                     G[u][Name[name]]=1;
    72                     G[Name[name]][u]=1;
    73                 }
    74                 per.push_back(Name[name]);
    75             }
    76         }
    77     }
    78     n=name_num;
    79     for(int i=1;i<=n;i++){
    80         for(int j=1;j<=n;j++){
    81             mp[i][j]=!G[i][j];
    82         }
    83     }
    84     printf("%d
    ",MaximumClique());
    85 //    while(cin >> n && n)
    86 //    {
    87 //        for(int i = 1; i <= n; ++i)
    88 //        for(int j = 1; j <= n; ++j)
    89 //        {
    90 //            int x; cin >> x;
    91 //            mp[i][j] = x;
    92 //        }
    93 //        cout << MaximumClique() << endl;
    94 //    }
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    流行的开源分布式文件系统比较
    Linux iostat监测IO状态
    M0n0wall软件防火墙教程
    networkscripts/ifcfg配置详解
    LVM 逻辑卷管理器
    Discuz 6.0数据库结构 四(详)
    Discuz 6.0数据库结构 二(详)
    手动配置linux(centos)的IP地址
    Discuz 6.0数据库结构 五(详)
    lnk快捷方式无法打开解决方法
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/10386804.html
Copyright © 2020-2023  润新知