Codeforces Round #290 (Div. 2)

Codeforces Round #290 (Div. 2)

 

C题:给你n个字符串要求你重新排列小写字母的字典序,要求使给的字符串按字典序从小到大排列。

 

思路:很容易想到相邻两串找到第一个不相同的建边,然后跑拓扑序就好啦。

 

 1 #include<bits/stdc++.h>
 2 #define fi first
 3 #define se second
 4 #define mk make_pair
 5 #define pii pair<int,int>
 6 #define read(x) scanf("%d",&x)
 7 #define sread(x) scanf("%s",x)
 8 #define dread(x) scanf("%lf",&x)
 9 #define lread(x) scanf("%lld",&x)
10 using namespace std;
11 
12 typedef long long ll;
13 const int inf=0x3f3f3f3f;
14 const ll INF=0x3f3f3f3f3f3f3f3f;
15 const int N=2000+7;
16 const int M=12;
17 
18 char s[105][105];
19 int len[105],topo[30],n,tot;
20 int vis[30];
21 
22 vector<int> edge[30];
23 
24 bool dfs(int u)
25 {
26     vis[u]=-1;
27     for(int v:edge[u])
28     {
29         if(vis[v]==-1)
30             return false;
31         if(vis[v]==0 && !dfs(v))
32             return false;
33     }
34     topo[tot--]=u;
35     vis[u]=1;
36     return true;
37 }
38 bool topo_sort()
39 {
40     tot=25;
41     for(int i=0;i<26;i++)
42         if(!vis[i] && !dfs(i))
43             return false;
44     return true;
45 }
46 int main()
47 {
48     read(n);
49     for(int i=1;i<=n;i++)
50         sread(s[i]+1),len[i]=strlen(s[i]+1);
51 
52     for(int i=1;i<n;i++)
53     {
54         bool flag=false;
55         for(int j=1;j<=len[i] && j<=len[i+1];j++)
56         {
57             if(s[i][j]!=s[i+1][j])
58             {
59                 edge[s[i][j]-'a'].push_back(s[i+1][j]-'a');
60                 flag=true;
61                 break;
62             }
63         }
64         if(!flag && len[i]>len[i+1])
65         {
66             puts("Impossible");
67             return 0;
68         }
69     }
70     if(!topo_sort())
71         puts("Impossible");
72     else
73     {
74         for(int i=0;i<26;i++)
75             printf("%c",topo[i]+'a');
76         puts("");
77     }
78     return 0;
79 }
80 /*
81 */
View Code

 

D题:有n个距离,选择一个距离都有一个花费,当你选择一条距离x的时候,你就能向左或者向右跳x格,问你最少花费多少就能

跳到数轴上任意位置。

 

思路:题目可以转化为要你选出一些距离,这些距离的gcd为1,最小花费为多少。 然后用map dp就行了。 dp[ i ]表示gcd为 i 时的最小花费。

 1 #include<bits/stdc++.h>
 2 #define fi first
 3 #define se second
 4 #define mk make_pair
 5 #define ll long long
 6 #define pll pair<ll,ll>
 7 #define pil pair<int,ll>
 8 #define pli pair<ll,int>
 9 #define pii pair<int,int>
10 #define read(x) scanf("%d",&x)
11 #define sread(x) scanf("%s",x)
12 #define dread(x) scanf("%lf",&x)
13 #define lread(x) scanf("%lld",&x)
14 using namespace std;
15 
16 const int N=300+7;
17 const int M=2e6+7;
18 const int inf=0x3f3f3f3f;
19 const ll INF=0x3f3f3f3f3f3f3f3f;
20 const int mod=1e9+7;
21 
22 int n;
23 pii a[N];
24 map<int,int> dp;
25 int main()
26 {
27     read(n);
28     for(int i=1;i<=n;i++)
29         read(a[i].fi);
30 
31     for(int i=1;i<=n;i++)
32         read(a[i].se);
33 
34     dp[0]=0;
35     map<int,int> :: iterator it;
36     for(int i=1;i<=n;i++)
37     {
38         int x=a[i].fi;
39         int c=a[i].se;
40         for(it=dp.begin(); it!=dp.end(); it++)
41         {
42             int y=it->first;
43             int d=__gcd(x,y);
44             int tmp=it->second+c;
45             if(dp[d] && dp[d]<tmp)
46                 continue;
47             dp[d]=tmp;
48         }
49     }
50     if(!dp[1])
51         puts("-1");
52     else
53         printf("%d\n",dp[1]);
54     return 0;
55 }
56 /*
57 */
View Code

 

E题:让你把n个数安排到任意个圆桌上,要求相邻的两个数加起来是素数。

 

思路:最大流,因为没有1,所以只有奇数和偶数相邻时才能为素数。 然后我们从原点向奇数建权值为2的边,偶数向

汇点建权值为2的边,然后加起来是素数的对应的奇数偶数之间建一条权值为1的边,跑最大流,看最大流是不是n。

  1 #include<bits/stdc++.h>
  2 #define fi first
  3 #define se second
  4 #define mk make_pair
  5 #define pii pair<int,int>
  6 #define read(x) scanf("%d",&x)
  7 #define sread(x) scanf("%s",x)
  8 #define dread(x) scanf("%lf",&x)
  9 #define lread(x) scanf("%lld",&x)
 10 using namespace std;
 11 
 12 typedef long long ll;
 13 const int inf=0x3f3f3f3f;
 14 const ll INF=0x3f3f3f3f3f3f3f3f;
 15 const int N=200+7;
 16 const int M=12;
 17 
 18 int n,S,T,tot,cnt,a[N],head[N],level[N];
 19 bool vis[N];
 20 
 21 vector<int> vec[N],ans[N];
 22 
 23 struct edge
 24 {
 25     int f,t,v,nx;
 26 }e[N*N];
 27 
 28 void add(int f,int t,int v)
 29 {
 30     e[tot].f=f; e[tot].t=t; e[tot].v=v;
 31     e[tot].nx=head[f]; head[f]=tot++;
 32 
 33     e[tot].f=t; e[tot].t=f; e[tot].v=0;
 34     e[tot].nx=head[t]; head[t]=tot++;
 35 }
 36 
 37 bool bfs()
 38 {
 39     memset(level,0,sizeof(level));
 40     queue<int> Q;
 41     Q.push(S); level[S]=1;
 42 
 43     while(!Q.empty())
 44     {
 45         int u=Q.front(); Q.pop();
 46         if(u==T)
 47             return true;
 48 
 49         for(int i=head[u];~i;i=e[i].nx)
 50         {
 51             int v=e[i].t;
 52             if(level[v] || !e[i].v)
 53                 continue;
 54 
 55             level[v]=level[u]+1;
 56             Q.push(v);
 57         }
 58 
 59     }
 60     return false;
 61 }
 62 
 63 int dfs(int u,int p)
 64 {
 65     if(u==T)
 66         return p;
 67     int ret=0;
 68     for(int i=head[u];~i;i=e[i].nx)
 69     {
 70         int v=e[i].t;
 71         if(level[v]!=level[u]+1 || !e[i].v)
 72             continue;
 73         int f=dfs(v,min(p-ret,e[i].v));
 74         ret+=f;
 75         e[i].v-=f;
 76         e[i^1].v+=f;
 77         if(ret==p)
 78             break;
 79     }
 80     if(!ret)
 81         level[u]=0;
 82     return ret;
 83 }
 84 
 85 int Dinic()
 86 {
 87     int ans=0;
 88     while(bfs())
 89         ans+=dfs(S,inf);
 90     return ans;
 91 }
 92 
 93 void cal(int u,int op)
 94 {
 95     vis[u]=true;
 96     ans[op].push_back(u);
 97     for(int v:vec[u])
 98         if(!vis[v])
 99             cal(v,op);
100 }
101 
102 bool is_prime(int x)
103 {
104     for(int i=2;i*i<=x;i++)
105         if(x%i==0)
106             return false;
107     return true;
108 }
109 
110 int main()
111 {
112     memset(head,-1,sizeof(head));
113     read(n);
114     for(int i=1;i<=n;i++)
115         read(a[i]);
116 
117     S=0,T=n+1;
118 
119     for(int i=1;i<=n;i++)
120     {
121         if(a[i]&1)
122             add(S,i,2);
123         else
124             add(i,T,2);
125     }
126 
127     for(int i=1;i<=n;i++)
128         for(int j=1;j<=n;j++)
129             if(a[i]&1 && is_prime(a[i]+a[j]))
130                 add(i,j,1);
131 
132     int ret=Dinic();
133 
134     if(ret!=n)
135         puts("Impossible");
136     else
137     {
138         for(int i=0;i<tot;i++)
139         {
140             if(e[i].f==S || e[i].t==S || e[i].f==T || e[i].t==T)
141                 continue;
142 
143             if(a[e[i].f]%2==1 && e[i].v==0)
144             {
145                 vec[e[i].f].push_back(e[i].t);
146                 vec[e[i].t].push_back(e[i].f);
147             }
148         }
149         for(int i=1;i<=n;i++)
150             if(!vis[i])
151                 cal(i,cnt++);
152         printf("%d\n",cnt);
153         for(int i=0;i<cnt;i++)
154         {
155             printf("%d ",ans[i].size());
156             for(int j:ans[i])
157                 printf("%d ",j);
158             puts("");
159         }
160     }
161     return 0;
162 }
163 /*
164 */
View Code

 

posted @ 2018-03-29 00:42  NotNight  阅读(229)  评论(0编辑  收藏  举报