第五周 3.28 --- 4.3

过了一个月了诶...

话说有种快要考试了的感觉TAT

3.28

继续没做完的拓扑排序

话说是去年挂的专题了TwT

poj 2585 Window Pains

和zoj 那题的建图一样,建出图来再判断是不是能够拓扑排序

注意重边

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<vector>
  7 using namespace std;
  8 
  9 int a[15][15],d[15];
 10 int g[15][15];
 11 
 12 void topsort(){
 13     queue<int> q;
 14     for(int i = 1;i <= 9;i++){
 15         if(d[i] == 0) q.push(i);
 16     }
 17     vector<int> ans;
 18     while(!q.empty()){
 19         int u = q.front();q.pop();
 20         ans.push_back(u);
 21     //    printf("u = %d\n",u);
 22         for(int i = 1;i <= 9;i++){
 23             if(!g[u][i]) continue;
 24             d[i]--;
 25             if(d[i] == 0) q.push(i);
 26         }
 27     }
 28     if(ans.size() == 9) puts("THESE WINDOWS ARE CLEAN");
 29     else puts("THESE WINDOWS ARE BROKEN");
 30 }
 31 
 32 
 33 void solve(){
 34     memset(g,0,sizeof(g));
 35     memset(d,0,sizeof(d));
 36     for(int i = 1;i <= 2;i++){
 37         for(int j = 1;j <= 2;j++){
 38             if(a[i][j] == 1) continue;
 39             int v = a[i][j];
 40             if(g[1][v]) continue;
 41             g[1][v] = 1;
 42             d[a[i][j]]++;
 43         }
 44     }
 45     for(int i = 1;i <= 2;i++){
 46         for(int j = 2;j <= 3;j++){
 47             if(a[i][j] == 2) continue;
 48             int v = a[i][j];
 49             if(g[2][v]) continue;
 50             g[2][v] = 1;
 51             d[a[i][j]]++;
 52         }
 53     }
 54     for(int i = 1;i <= 2;i++){
 55         for(int j = 3;j <= 4;j++){
 56             if(a[i][j] == 3) continue;
 57             int v = a[i][j];
 58             if(g[3][v]) continue;
 59             g[3][v] = 1;
 60             d[a[i][j]]++;
 61         }
 62     }
 63     //第一行的完了
 64     for(int i = 2;i <= 3;i++){
 65         for(int j = 1;j <= 2;j++){
 66             if(a[i][j] == 4) continue;
 67             int v = a[i][j];    
 68             if(g[4][v]) continue;
 69             g[4][v] = 1;
 70             d[a[i][j]]++;
 71         }
 72     }
 73     for(int i = 2;i <= 3;i++){
 74         for(int j = 2;j <= 3;j++){
 75             if(a[i][j] == 5) continue;
 76             int v = a[i][j];
 77             if(g[5][v]) continue;
 78             g[5][v] = 1;
 79             d[a[i][j]]++;
 80         }
 81     }
 82     for(int i = 2;i <= 3;i++){
 83         for(int j = 3;j <= 4;j++){
 84             if(a[i][j] == 6) continue;
 85             int v = a[i][j];
 86             if(g[6][v]) continue;
 87             g[6][v] = 1;
 88             d[a[i][j]]++;
 89         }
 90     }
 91     //第二行的完了
 92     for(int i = 3;i <= 4;i++){
 93         for(int j = 1;j <= 2;j++){
 94             if(a[i][j] == 7) continue;
 95             int v = a[i][j];
 96             if(g[7][v]) continue;
 97             g[7][v] = 1;
 98             d[a[i][j]]++;
 99         }
100     }
101     for(int i = 3;i <= 4;i++){
102         for(int j = 2;j <= 3;j++){
103             if(a[i][j] == 8) continue;
104             int v = a[i][j];
105             if(g[8][v]) continue;
106             g[8][v] = 1;
107             d[a[i][j]]++;
108         }
109     }
110     for(int i = 3;i <= 4;i++){
111         for(int j = 3;j <= 4;j++){
112             if(a[i][j] == 9) continue;
113             int v = a[i][j];
114             if(g[9][v]) continue;
115             g[9][v] = 1;
116             d[a[i][j]]++;
117         }
118     }
119     topsort();
120 }
121 
122 int main(){
123     string s;
124     while(cin >> s){
125         if(s == "ENDOFINPUT") break;
126         for(int i = 1;i <= 4;i++){
127             for(int j = 1;j <= 4;j++) scanf("%d",&a[i][j]);
128         }
129         cin >> s;
130         solve();
131     }
132 }
View Code

 

hdu 3342 Legal or Not

拓扑排序

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<vector>
 7 using namespace std;
 8 
 9 const int maxn = 105;
10 int g[maxn][maxn],n,m,d[maxn];
11 
12 void topsort(){
13     queue<int> q;
14     vector<int> ans;
15     for(int i = 1;i <= n;i++){
16         if(d[i] == 0) q.push(i);
17     }
18     while(!q.empty()){
19         int u = q.front();q.pop();
20         ans.push_back(u);
21         for(int i = 1;i <= n;i++){
22             if(g[u][i]){
23                 d[i]--;
24                 if(d[i] == 0) q.push(i);
25             }
26         }
27     }
28     if(ans.size() == n) puts("YES");
29     else puts("NO");
30 }
31 
32 int main(){
33     while(scanf("%d %d",&n,&m) != EOF){
34         if(n == 0) break;
35         memset(g,0,sizeof(g));
36         memset(d,0,sizeof(d));
37         int u,v;
38         for(int i = 1;i <= m;i++){
39             scanf("%d %d",&u,&v);
40             u++;v++;
41             if(g[u][v]) continue;
42             g[u][v] = 1;
43             d[v]++;
44         }
45         topsort();
46     }
47     return 0;
48 }
View Code

 

3.29

...

3.30

cf 274d Lovely Matrix

直接建图,边太多了

不会做

题解是

如果是这样的序列 1 1 1 2 2

按照最初的建图,每个 1 都要向2连边

这里 可以一个 v1 连向所有的 1 ,1 向v2 连边 ,v2向2连边

然后再拓扑排序

建图感觉有点像Meeting

都是增加虚拟的点

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<queue>
 7 using namespace std;
 8 
 9 int n,m,cnt;
10 const int maxn = 5e5+5;
11 int d[maxn];
12 vector<int> g[maxn];
13 
14 struct node{
15     int id,x;
16 }p[maxn];
17 
18 int cmp(node n1,node n2){
19     return n1.x < n2.x;
20 }
21 
22 void topsort(){
23     queue<int> q;
24     vector<int> ans;
25     for(int i = 1;i <= m+cnt;i++){
26         if(d[i] == 0) q.push(i);
27     }
28     while(!q.empty()){
29         int u = q.front();q.pop();
30         ans.push_back(u);
31         for(int i = 0;i < g[u].size();i++){
32             int v = g[u][i];
33             d[v]--;
34             if(d[v] == 0) q.push(v);
35         }
36     }
37     if(ans.size() == m+cnt){
38         for(int i = 0;i < ans.size();i++){
39             if(ans[i] <= m) printf("%d ",ans[i]);
40         }
41         printf("\n");
42         return;
43     }
44     puts("-1");
45 }
46 
47 int main(){
48     while(scanf("%d %d",&n,&m) != EOF){
49         cnt = 0;
50         for(int i = 0;i < maxn;i++) g[i].clear();
51         for(int i = 1;i <= n;i++){
52             for(int j = 1;j <= m;j++){
53                 scanf("%d",&p[j].x);
54                 p[j].id = j;
55             }
56             sort(p+1,p+m+1,cmp);
57             for(int j = 1;j <= m;j++){
58                 if(p[j].x == -1) continue;
59                 if(j == 1 || p[j].x != p[j-1].x) cnt++;
60                 int a = m+cnt+1;
61                 int b = m+cnt;
62                 int c = p[j].id;
63             //    printf("i = %d a = %d b = %d c = %d cnt = %d \n",i,a,b,c,cnt);
64                 g[b].push_back(c);
65                 g[c].push_back(a);
66             }
67             cnt++;
68         }
69         memset(d,0,sizeof(d));
70         for(int i = 1;i <= m+cnt;i++){
71             for(int j = 0;j < g[i].size();j++){
72                 int v = g[i][j];
73                 d[v]++;
74             }
75         }
76     //    for(int i = 1;i <= m+cnt;i++) printf("d[%d] = %d\n",i,d[i]);
77         topsort();
78     }
79     return 0;
80 }
View Code

 

3.31

uva 10129 Play on Words

欧拉道路

wa了两发,是因为,判断连通性的时候,用的dfs,然后碰到一个没有搜过的点就去搜

应该是从有出边的节点去搜

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1e5+5;
 8 char s[maxn];
 9 int n,in[maxn],out[maxn];
10 int g[105][105],vis[105];
11 
12 void dfs(int u){
13     vis[u] = 1;
14     for(int i = 1;i <= 26;i++){
15         if(g[u][i] && !vis[i]){
16                 dfs(i);
17         }
18     }
19 }
20 
21 void solve(){
22     int c = 0,tot = 0;
23     for(int i = 1;i <= 26;i++){
24         if(in[i] || out[i]) tot++;
25     }
26     for(int i = 1;i <= 26;i++){
27         if(in[i] == 0 && out[i] == 0) continue;
28         if(!vis[i] && out[i]){
29             dfs(i);
30             c++;
31         }
32     }
33     //printf("c = %d\n",c);
34     //for(int i = 1;i <= 26;i++) printf("in[%c] = %d out[%c] = %d\n",i+'a'-1,in[i],i+'a'-1,out[i]);
35     if(c >= 2){
36         puts("The door cannot be opened.");
37         return;
38     }
39 //    printf("c = %d tot = %d\n",c,tot);
40     int l = 0,r = 0,cc = 0;
41     for(int i = 1;i <= 26;i++){
42         if(vis[i] == 0) continue;
43         if((out[i]-in[i]) == 1){
44              l++;
45              continue;
46         }
47         if((in[i]-out[i]) == 1) {
48             r++;
49             continue;
50         }
51         if(in[i] != out[i]) cc++;
52     }
53     if((l+r) > 2 || cc != 0 ){
54         puts("The door cannot be opened.");
55         return;
56     }
57     puts("Ordering is possible.");
58 }
59 
60 int main(){
61     int T;
62     scanf("%d",&T);
63     while(T--){
64         memset(in,0,sizeof(in));
65         memset(out,0,sizeof(out));
66         memset(g,0,sizeof(g));
67         memset(vis,0,sizeof(vis));
68         scanf("%d",&n);
69         for(int i = 1;i <= n;i++){
70             scanf("%s",s+1);
71             int len = strlen(s+1);
72             int u = s[1]-'a'+1;
73             int v = s[len]-'a'+1;
74             g[u][v] = 1;
75             out[u]++;
76             in[v]++;
77         }
78         solve();
79     }
80     return 0;
81 }
View Code

 

4.1

四月一日><

 

4.2

做了 April fools day 的比赛,果然 sb 就是 sb  

纪念下cf 656b Scrambled

比赛的时候不知道怎么做,,,于是随机了50个数算概率,水果......

今天看题解才知道做法TAT

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <ctime>
 6 
 7 using namespace std;
 8 int n;
 9 int m[105],r[105];
10 int p[10];
11 
12 void solve(){
13     double ans = 0.0;
14     for(int i = 6;i <= 6;i++){
15         int rr = p[i];
16         double tmp =0.0;
17         for(int k = 1;k <= 50;k++){
18             int x = rand()%rr + rr;
19             int cc = 0;
20             for(int j = 0;j <= x;j++){
21                 for(int z = 1;z <= n;z++){
22                     if((j%m[z]) == r[z]) {
23                         cc++;
24                         break;
25                     }
26                 }
27             }
28             tmp += (1.0*cc)/(1.0*x+1.0);
29         }
30         tmp = tmp/50.0;
31         ans += tmp;
32     }
33     printf("%.9lf\n",ans/1.0);
34     
35 }
36 
37 int main(){
38     p[1] = 10;
39     for(int i = 2;i <= 9;i++) p[i] = p[i-1]*10;
40     srand((unsigned)time(NULL));
41     while(scanf("%d",&n) != EOF){
42         for(int i = 1;i <= n;i++) scanf("%d",&m[i]);
43         for(int i = 1;i <= n;i++) scanf("%d",&r[i]);
44         solve();
45 
46     }
47     
48     return 0;
49 }
View Code

 

做bc ,GG ....

一点都没有想到要去dp,做得少还想得少....sad

hdu 5657 CA Loves GCD

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const LL mod = 1e8+7;
 9 const int maxn = 1005;
10 LL dp[maxn][maxn];
11 int n,a[maxn];
12 
13 int gcd(int a,int b){return (!b)? a:gcd(b,a%b);}
14 
15 void solve(){
16     memset(dp,0LL,sizeof(dp));
17     for(int i = 1;i <= n;i++) dp[i][a[i]] = 1LL;
18     for(int i = 2;i <= n;i++){
19         for(int j = 1;j <= 1000;j++){
20             dp[i][j] = (dp[i][j] + dp[i-1][j])%mod;
21             if(dp[i-1][j]){
22                 dp[i][gcd(j,a[i])] = (dp[i][gcd(j,a[i])]+dp[i-1][j])%mod;
23             }
24         }
25     }
26 /*    for(int i = 1;i <= 10;i++){
27         for(int j = 1;j <= 10;j++){
28             if(dp[i][j]) printf("dp[%d][%d] = %I64d\n",i,j,dp[i][j]);
29         }
30     }*/
31     LL ans = 0LL;
32     for(int i = 1;i <= 1000;i++){
33         if(dp[n][i] == 0) continue;
34         LL tmp = (dp[n][i]*i)%mod;
35         ans = (ans+tmp)%mod;
36     }
37     printf("%I64d\n",ans);
38 }
39 
40 int main(){
41     int T;
42     scanf("%d",&T);
43     while(T--){
44         scanf("%d",&n);
45         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
46         solve();
47     }
48     return 0;
49 }
View Code

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/5329738.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值