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\n",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("\n");
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\n",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

 

posted @ 2019-02-16 09:45  蒟蒻LQL  阅读(182)  评论(0编辑  收藏  举报