第二周 3.7 --- 3.13

本文分享了编程领域的多个算法和技巧,包括数据结构、排序、动态规划等,并涉及了多种编程语言的应用实例。

3.7

cf 631 d D - Messenger

不懂写

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 
  8 typedef long long LL;
  9 const int maxn = 2e5+5;
 10 int N,M,n,m,lena,lenb;
 11 int p[maxn];
 12 char s[maxn],t[maxn];
 13 
 14 //gan ba die >_</
 15 
 16 struct node{
 17     char c;
 18     LL x;
 19 };
 20 
 21 node a[maxn],b[maxn],c[maxn],d[maxn];
 22 
 23 void Get_p(){
 24     p[1] = 0;
 25     int j = 0;
 26     for(int i = 2;i <= lenb;i++){
 27         while(j > 0 && (b[j+1].c != b[i].c || b[j+1].x != b[i].x)) j =p[j];
 28         if(b[j+1].c == b[i].c && b[j+1].x == b[i].x) j++;
 29         p[i] = j;
 30     }
 31     //for(int i = 1;i <= lenb;i++) printf("p[%d] = %d\n",i,p[i]);
 32 }
 33 
 34 void KMP(){
 35     Get_p();
 36     int ans = 0;
 37     int j = 0;
 38     for(int i = 1;i <= lena;i++){
 39         if(j == lenb-1 && b[j+1].c == a[i].c && b[j+1].x <= a[i].x) {
 40             j++;
 41         }
 42         else{
 43             while(j > 0 && (b[j+1].c != a[i].c || b[j+1].x != a[i].x)) j = p[j];
 44             if(j == 0 && b[j+1].c == a[i].c && b[j+1].x <= a[i].x) j++;
 45             else if(b[j+1].c == a[i].c && b[j+1].x == a[i].x) j++;
 46         }
 47         if(j == lenb){
 48             //printf("--- i = %d j = %d ",i,j);
 49             if(a[i].x != b[p[j]].x){
 50                 j = 0;
 51                 ans++;
 52                 i--;
 53             }
 54             else{
 55                 j = p[j];
 56                 ans++;
 57             }    
 58             //printf(" i = %d j = %d\n",i,j);
 59         }
 60     }
 61 
 62     printf("%d\n",ans);
 63 }
 64 
 65 void solve(){
 66     int cnt = 0;
 67     for(int i = 1;i <= N;){
 68         int j = i;
 69         LL tmp = 0;
 70         while(j <= N && c[j].c == c[i].c){
 71             tmp += c[j].x;
 72             j++;
 73         }
 74         a[++cnt].c = c[i].c;
 75         a[cnt].x = tmp;
 76         i = j;
 77     }
 78     lena = cnt;
 79     cnt = 0;
 80     for(int i = 1;i <= M;){
 81         int j = i;
 82         LL tmp = 0;
 83         while(j <= M && d[j].c == d[i].c){
 84             tmp += d[j].x;
 85             j++;
 86         }
 87         b[++cnt].c = d[i].c;
 88         b[cnt].x = tmp;
 89         i = j;
 90     }
 91     lenb = cnt;
 92 
 93     //for(int i = 1;i <= lena;i++) printf("%c %d\n",a[i].c,a[i].x);
 94     //for(int i = 1;i <= lenb;i++) printf("%c %d\n",b[i].c,b[i].x);
 95 
 96     if(lenb == 1){
 97         LL res = 0LL;
 98         for(int i = 1;i <= lena;i++){
 99             if(a[i].x >= b[1].x && a[i].c == b[1].c){
100                 res += 1LL*(a[i].x - b[1].x+1);
101             }
102         }
103         printf("%I64d\n",res);
104         return;
105     }
106 
107     KMP();
108 
109 }
110 
111 int main(){
112     while(scanf("%d %d",&N,&M) != EOF){
113         char ch;
114         for(int i = 1;i <= N;i++){
115             scanf("%I64d",&c[i].x);
116             scanf("%c",&ch);
117             scanf("%c",&c[i].c);
118         }
119         for(int i = 1;i <= M;i++){
120             scanf("%I64d",&d[i].x);
121             scanf("%c",&ch);
122             scanf("%c",&d[i].c);
123         }
124         solve();
125     }
126     return 0;
127 }
View Code

 

cf 632d D - Longest Subsequence

想的是去枚举从 1 到m的每个数作为lcm,可是没有想到用dp....sad

dp[i] 表示以i 为LCM 的有多少个数

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1e6+5;
 8 int n,m;
 9 int a[maxn],dp[maxn],c[maxn];
10 
11 void solve(){
12     memset(dp,0,sizeof(dp));
13     for(int i = 1;i <= m;i++){
14         for(int j = i;j <= m;j+=i){
15             dp[j] += c[i];
16         }
17     }
18     int l = 0,r = 0;
19     for(int i = 1;i <= m;i++){
20         if(dp[i] > r){
21             r = dp[i];
22             l = i;
23         }
24     }
25     if(r == 0) l = 1;
26     printf("%d %d\n",l,r);
27     if(r == 0) return;
28     for(int i = 1;i <= n;i++){
29         if(l%a[i] == 0) printf("%d ",i); 
30     }
31     printf("\n");
32 
33 }
34 
35 int main(){
36     while(scanf("%d %d",&n,&m) != EOF){
37         memset(c,0,sizeof(c));
38         for(int i = 1;i <= n;i++) {
39             scanf("%d",&a[i]);
40             if(a[i] <= m) c[a[i]]++;
41         }
42         solve();
43     }
44     return 0;
45 }
View Code

 

3.8

去了一个宣讲会......什么技能都没有.....

累成狗><

老哥曰:慢慢找,可以找到明年的这个时候.......5555555555

 

3.9

cf 651c 651C - Watchmen

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<map>
 7 using namespace std;
 8 
 9 typedef long long LL;
10 const int maxn = 2e5+5;
11 int n,l[maxn],r[maxn];
12 map<int,int> x;
13 map<int,int> y;
14 map<pair<int,int>,int> xy;
15 
16 void solve(){
17     LL lb = 0LL,ub = 0LL,mid = 0LL;
18     LL tmp = 0LL;
19     for(map<int,int>::iterator it = x.begin();it != x.end();++it){
20         tmp = it->second;
21         //printf("tmp = %I64d\n",tmp);
22         if(tmp <= 1) continue;
23         lb += 1LL*tmp*(tmp-1LL)/2LL;
24     }
25     for(map<int,int>::iterator it = y.begin();it != y.end();++it){
26         tmp = it->second;
27         //printf("tmp = %I64d\n",tmp);
28         if(tmp <= 1) continue;
29         ub += 1LL*tmp*(tmp-1LL)/2LL;
30     }
31     for(map<pair<int,int>,int>::iterator it = xy.begin();it != xy.end();++it){
32         tmp = it->second;
33         if(tmp <= 1) continue;
34         mid += 1LL*tmp*(tmp-1LL)/2LL;
35     }
36     LL ans = lb+ub-mid;
37     printf("%I64d\n",ans);
38 }
39 
40 int main(){
41     while(scanf("%d",&n) != EOF){
42         x.clear();
43         y.clear();
44         xy.clear();
45         for(int i = 1;i <= n;i++){
46             scanf("%d %d",&l[i],&r[i]);
47             x[l[i]]++;y[r[i]]++;
48             xy[make_pair(l[i],r[i])]++;
49         }
50         solve();
51     }
52     return 0;
53 }
View Code

 

3.10

cf 651d D - Image Preview

感觉做法很好理解,可是不好写

参考别人的代码,也调了好久,好挫啊><

觉得很难写的地方是,先一直左滑,再向右滑;和先右滑再左滑

而且没有想到去预处理一个数组出来

还有就是无论怎么滑,第一张照片都是不能跳过的

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 5e5+5;
 8 char s[maxn],rs[maxn],t[maxn];
 9 int d[maxn],n,m,a,b;
10 int ans;
11 
12 int solve(int key){
13     memset(d,0,sizeof(d));
14     if(key == 0){
15         for(int i = 1;i <= n;i++) s[i] = t[i];
16     }
17     else {
18         s[1] = t[1];
19         for(int i = 1;i <= n-1;i++) s[i+1] = t[n-i+1];
20     }
21     //printf("---key = %d  s= %s---\n",key,s+1);
22     int L = 0,R = n;
23     d[1] = 1 + (s[1] == 'h'?0:b);
24     //printf("d[1] = %d\n",d[1]);
25     for(int i = 2;i <= n;i++){
26         d[i] = d[i-1] + a+1 +(s[i] == 'h'?0:b);
27         if(d[i] > m){
28             R = i-1;
29             break;
30         }
31     //    printf("d[%d] = %d\n",i,d[i]);
32     }
33     if(d[1] > m){return 0;}
34     if(R == 1){return 1;}
35 
36     ans = R;
37     //printf("R = %d\n",R);
38     L = n;
39     int zz = (R-1)*a;
40     while(R >= 1){
41         while(zz + d[R] +a+1+(s[L] == 'h'?0:b) <= m && (R+n-L) < n){
42             zz += a+1+(s[L] == 'h'?0:b);
43     //        printf("-- R  = %d L = %d\n",R,L);
44             L--;
45         }
46         ans = max(ans,R+n-L);
47         if(ans >= n){return n;}
48         zz -= a;
49         R--;
50     }
51     //printf(">_< ans = %d\n",ans);
52     return ans;
53 }
54 
55 int main(){
56     while(scanf("%d %d %d %d",&n,&a,&b,&m) != EOF){
57         scanf("%s",t+1);
58         memset(d,0,sizeof(d));
59         int res = 0;
60         res = max(solve(0),solve(1));
61         printf("%d\n",res);
62     }
63     return 0;
64 }
View Code

 

3.11

记录下两次面试,自己好水

3.9 面蘑菇街 

哈希,排序,快排的复杂度,什么时候退化成O(n^2),set怎么实现的

堆排,怎么把一颗二叉树调成平衡的

3.10 面阿里

讲解一下 dinic ,二分图匹配;Floyed 的k 为什么放最外面

GG.............

 

3.12

sb 打表没有打完

hdu 5641 King's Phone

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 int n,k;
 9 int a[105];
10 vector<int> g[15][15];
11 int vis[105];
12 int cnt[105];
13 
14 void solve(){
15     if(n < 4 || n > 9){
16         puts("invalid");
17         return;
18     }
19     memset(vis,0,sizeof(vis));
20 
21     for(int i = 1;i <= n;i++){
22         if(a[i] == 0 || a[i] > 9){
23             puts("invalid");
24             return;
25         }
26     }
27     memset(cnt,0,sizeof(cnt));
28     for(int i = 1;i <= n;i++){
29         cnt[a[i]]++;
30         if(cnt[a[i]] >= 2){
31             puts("invalid");
32             return;
33         }
34     }
35 
36     for(int i = 1;i <= n-1;i++){
37         int u = a[i];
38         int v = a[i+1];
39         if(g[u][v].size() == 0){
40             vis[u] = 1;
41             vis[v] = 1;
42         }
43         else{
44             int z = g[u][v][0];
45             if(vis[z] == 0){
46                 puts("invalid");
47                 return;
48             }
49             vis[u] = 1;
50             vis[v] = 1;
51         }
52     }
53     puts("valid");
54 }
55 
56 int main(){
57     int T;
58     g[1][3].push_back(2);
59     g[1][7].push_back(4);
60     g[1][9].push_back(5);
61     g[2][8].push_back(5);
62     g[3][7].push_back(5);
63     g[3][9].push_back(6);
64     g[4][6].push_back(5);
65     g[7][9].push_back(8);
66 
67     g[3][1].push_back(2);
68     g[7][1].push_back(4);
69     g[9][1].push_back(5);
70     g[8][2].push_back(5);
71     g[7][3].push_back(5);
72     g[9][3].push_back(6);
73     g[6][4].push_back(5);
74     g[9][7].push_back(8);
75     scanf("%d",&T);
76     while(T--){
77         scanf("%d",&n);
78         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
79         solve();
80     }
81     return 0;
82 }
View Code

 

3.13

hdu 5642 King's Order

比赛的时候一直想容斥

感觉是 dp,容斥,组合数学都做得太少,碰到题目连类型是什么都不知道了

dp[i][j] 表示到前 i 个位置 末尾有 j个是相同的

注意dp[i][1] 可以是任意的dp[i-1][j] 在末尾填上和i-1位不同的都可以

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int mod = 1e9+7;
 9 LL dp[5005][105];
10 int n;
11 
12 void Pre(){
13     memset(dp,0,sizeof(dp));
14     dp[1][1] = 26LL;
15     for(int i = 2;i <= 2000;i++){
16         dp[i][2] = (dp[i][2]+dp[i-1][1])%mod;
17         dp[i][3] = (dp[i][3]+dp[i-1][2] )%mod;
18         dp[i][1] = (dp[i][1]+(dp[i-1][1]+dp[i-1][2]+dp[i-1][3])*25)%mod;
19     //    printf("dp[%d][1] = %I64d dp[%d][2] = %I64d dp[%d][3] = %I64d\n",i,dp[i][1],i,dp[i][2],i,dp[i][3]);
20     }
21 /*    for(int i = 1;i <= 10;i++)
22         for(int j = 1;j <= 3;j++) printf("dp[%d][%d] = %I64d\n",i,j,dp[i][j]);*/
23 }
24 
25 int main(){
26     int T;    
27     scanf("%d",&T);
28     Pre();
29     while(T--){
30         scanf("%d",&n);
31         LL ans = dp[n][1] + dp[n][2] + dp[n][3];
32         printf("%I64d\n",ans%mod);
33 
34     }
35     return 0;
36 }
View Code

 

hdu 5643 King's Game

约瑟夫环

题解讲得很清楚了

要滚动一下

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int dp[2][5005];
 8 int n;
 9 int ans[5005];
10 
11 void Pre(){
12     memset(dp,0,sizeof(dp));
13     int key = 1;
14     for(int i = 1;i <= 5000;i++){
15         for(int j = 1;j <= 5000;j++){
16             dp[key][j] = (dp[1-key][j+1]+j)%i;
17         //    printf("dp[%d][%d] = %d\n",i,j,dp[i][j]);
18         }
19         ans[i] = dp[key][1]+1;
20         for(int j = 1;j <= 5000;j++) dp[1-key][j] = dp[key][j];
21         key = !key;
22     }
23     //for(int i = 1;i <= 10;i++) printf("ans[%d] = %d\n",i,ans[i]+1);
24 }
25 
26 int main(){
27     int T;
28     Pre();
29     scanf("%d",&T);
30     while(T--){
31         scanf("%d",&n);
32         printf("%d\n",ans[n]);
33     }
34     return 0;
35 }
View Code

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值