codeforces#541 1131a-----1131f
Posted pandaking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces#541 1131a-----1131f相关的知识,希望对你有一定的参考价值。
a:没啥,主要是要手速快,不过我手速显然不够快,阅读能力不行啊。。。。。。
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 typedef long long ll; 6 ll w1,h1,w2,h2; 7 int main(){ 8 scanf("%lld%lld%lld%lld",&w1,&h1,&w2,&h2); 9 printf("%lld ",(h1+h2)*2+2*(w1+2)); 10 return 0; 11 }
b:同上
1 By Pnada_Kinggggggggggggg, contest: Codeforces Round #541 (Div. 2), problem: (B) Draw!, Accepted, # 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 #include <cstdio> 6 #include <cmath> 7 #include <bitset> 8 using namespace std; 9 typedef long long ll; 10 const int maxn=10100; 11 int n; 12 struct node{ 13 ll xi,yi; 14 }; 15 node sum[maxn]; 16 int main(){ 17 scanf("%d",&n); 18 sum[0].xi=0;sum[0].yi=0; 19 for(int i=1;i<=n;i++) scanf("%lld%lld",&sum[i].xi,&sum[i].yi); 20 ll ans=1; 21 for(int i=1;i<=n;i++){ 22 if(sum[i-1].xi<sum[i-1].yi){ 23 if(sum[i].xi>=sum[i-1].yi) ans+=min(sum[i].xi-sum[i-1].yi+1,sum[i].yi-sum[i-1].yi+1); 24 }else if(sum[i-1].xi>sum[i-1].yi){ 25 if(sum[i].yi>=sum[i-1].xi) ans+=min(sum[i].xi-sum[i-1].xi+1,sum[i].yi-sum[i-1].xi+1); 26 }else{ 27 ans+=min(sum[i].xi-sum[i-1].yi,sum[i].yi-sum[i-1].xi); 28 } 29 } 30 printf("%lld ",ans); 31 return 0; 32 }
c:同上
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 typedef long long ll; 8 int n; 9 ll num[130]; 10 ll a[130]; 11 int main(){ 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++) scanf("%lld",&num[i]); 14 sort(num+1,num+n+1); 15 if(n%2==1){ 16 int len=n/2+1; 17 a[len]=num[n];len--; 18 int cnt=1; 19 for(int i=len;i>=1;i--){ 20 a[i]=num[n-cnt]; 21 a[n-i+1]=num[n-cnt-1]; 22 cnt+=2; 23 } 24 }else{ 25 int len=n/2; 26 int cnt=0; 27 for(int i=len;i>=1;i--){ 28 a[i]=num[n-cnt]; 29 a[n-i+1]=num[n-cnt-1]; 30 cnt+=2; 31 } 32 } 33 for(int i=1;i<n;i++) printf("%lld ",a[i]); 34 printf("%lld ",a[n]); 35 return 0; 36 }
d:题意:第一天有n个菜,第二天有m个菜,給一个n*m矩阵, 含有 > = <三个字符, a(i,j)指的是:第一天的第i件菜的美味度 > = <第二天的第j件菜的美味度。求出满足这个矩阵的n+m件菜的各自的美味度,
要求使用的最大数字尽量小。
首先说怎么去想吧:这个很容易往图的方向去想,然后就可以想到拓扑排序。那么怎么解决相等这个问题了,这个就可以想到并查集了,数据结构的重要性啊。。。。。
启发: 1:不要用两个数组,用一个数组就可以想到图的方向 2:然后判相等可以用并查集
然后就没啥了,接下来是代码:
1 #include <algorithm> 2 #include <cstring> 3 #include <iostream> 4 #include <cstdio> 5 #include <cmath> 6 #include <vector> 7 #include <bitset> 8 #include <queue> 9 using namespace std; 10 int n,m; 11 vector<int> G[2200]; 12 char sz[1010][1010]; 13 int f[2100]; 14 int in[2100]; 15 int ans[2100]; 16 17 int find(int x){ 18 if(f[x]==x) return x; 19 else return find(f[x]); 20 } 21 22 bool toposort(){ 23 queue<int> que; 24 for(int i=1;i<=n+m;i++){ 25 if(i==find(i)&&in[find(i)]==0){ 26 que.push(i);ans[i]=1; 27 } 28 } 29 while(!que.empty()){ 30 int u=que.front();que.pop(); 31 for(int i=0;i<G[u].size();i++){ 32 int v=G[u][i]; 33 in[v]--; 34 if(in[v]==0){ 35 que.push(v); 36 ans[v]=ans[u]+1; 37 } 38 } 39 } 40 for(int i=1;i<=n+m;i++) if(!ans[find(i)]) return false; 41 else return true; 42 } 43 44 int main(){ 45 scanf("%d%d",&n,&m); 46 for(int i=1;i<=n+m;i++) f[i]=i; 47 for(int i=1;i<=n;i++){ 48 scanf("%s",sz[i]+1); 49 for(int j=1;j<=m;j++){ 50 if(sz[i][j]==‘=‘){ 51 int t1=find(i),t2=find(j+n); 52 f[t1]=t2; 53 } 54 } 55 } 56 for(int i=1;i<=n;i++){ 57 for(int j=1;j<=m;j++){ 58 int t1=find(i),t2=find(j+n); 59 if(sz[i][j]==‘>‘){ 60 G[t2].push_back(t1); 61 in[t1]++; 62 } 63 if(sz[i][j]==‘<‘){ 64 G[t1].push_back(t2); 65 in[t2]++; 66 } 67 } 68 } 69 if(!toposort()) printf("No "); 70 else{ 71 printf("Yes "); 72 for(int i=1;i<=n;i++) printf("%d ",ans[find(i)]); 73 printf(" "); 74 for(int i=n+1;i<=n+m;i++) printf("%d ",ans[find(i)]); 75 printf(" "); 76 } 77 return 0; 78 }
e:题意,定义一种字符串操作 有两个字符串s和t s*t 就会变成一个新的字符串 t+s1+t+s2+t......+sn+t;
然后给你n个字符串,求这n个字符串连续乘积的和中连续出现的字符的最大个数!
首先:这应该是一个很想的递推把,设f[i][j]为第i次操作形成的字符串中字符j出现的次数,那么考虑两种情况,便很好就可以从两种情况下手,第一种情况就是这个新的字符串都是
j这个字符和不是的这两种情况。
启发: 1:这种题目应该在草稿纸上面捋清楚思绪再写的
代码:
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstdio> 6 #include <bitset> 7 using namespace std; 8 const int maxn=100100; 9 int S=26; 10 int n; 11 int dp[maxn][26]; 12 int pre[26],suf[26]; 13 char sz[maxn]; 14 15 void solve(int *f){ 16 scanf("%s",sz+1); 17 int len=strlen(sz+1); 18 for(int i=0;i<S;i++){ 19 int mx=0; 20 int now=0; 21 for(int j=1;j<=len;j++){ 22 if(i==(sz[j]-‘a‘)) mx=max(mx,++now); 23 else now=0; 24 } 25 f[i]=mx;pre[i]=0,suf[i]=0; 26 for(int j=1;j<=len;j++){ 27 if(i==(sz[j]-‘a‘)) pre[i]++; 28 else break; 29 } 30 for(int j=len;j>=1;j--){ 31 if(i==(sz[j]-‘a‘)) suf[i]++; 32 else break; 33 } 34 } 35 } 36 37 int main(){ 38 scanf("%d",&n); 39 solve(dp[1]); 40 for(int i=2;i<=n;i++){ 41 solve(dp[i]); 42 int len=strlen(sz+1); 43 for(int j=0;j<S;j++) { 44 if(dp[i-1][j]>0){ 45 if (pre[j]==len) dp[i][j] = max(dp[i][j], len * (dp[i - 1][j] + 1) + dp[i - 1][j]); 46 else dp[i][j] = max(dp[i][j], pre[j] + suf[j] + 1); 47 } 48 } 49 } 50 int ans=0; 51 for(int i=0;i<S;i++) ans=max(ans,dp[n][i]); 52 printf("%d ",ans); 53 return 0; 54 }
f:给你n个点,每次你可以合并相邻的两个点,会给你n-1次合并机会,要你求最开始可能出现的排列情况
这个我一开始往带权并差集上面想了,结果发现不用,我只要按基础并查集的操作建一颗树就够了,是我想的太复杂了
接下来是代码:
1 #include <bits/stdc++.h> 2 #define maxn 150005 3 using namespace std; 4 int pre[maxn]; 5 int n; 6 vector<int> v[maxn]; 7 8 void init(){ 9 for(int i=0;i<=n;i++){ 10 pre[i] = i; 11 } 12 } 13 14 void dfs(int x){ 15 printf("%d ", x); 16 for(int i=0;i<v[x].size();i++) dfs(v[x][i]); 17 } 18 19 int Find(int x){ 20 if(x != pre[x]){ 21 pre[x] = Find(pre[x]); 22 } 23 return pre[x]; 24 } 25 26 void merge(int x,int y){ 27 int fx = Find(x); 28 int fy = Find(y); 29 if(fx != fy){ 30 pre[fy] = fx; 31 v[fx].push_back(fy); 32 } 33 } 34 35 int main() 36 { 37 scanf("%d",&n); 38 init(); 39 for(int i=1;i<n;i++){ 40 int u, v; 41 scanf("%d%d",&u, &v); 42 merge(u, v); 43 } 44 dfs(Find(1)); 45 return 0; 46 }
以上是关于codeforces#541 1131a-----1131f的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #541 (Div. 2) 题解
Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序
Codeforces Round #541 (Div. 2) E 字符串 + 思维 + 猜性质