Codeforces Round #500 (Div.1)
Posted absi2011
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #500 (Div.1)相关的知识,希望对你有一定的参考价值。
题意:
A
给你2n个数字,你可以任意排列
让你排成n个坐标
然后让一个平行于坐标轴的矩形包含这n个坐标
问矩形大小的最小值
n<=1e5
B
给你n*m的方格,已知任意三个点如果这样就可以生成另一个点(见下图)
生成的点可以用来生成别的店,之前的三个点也还在
现在给你q个点,问你至少加几个点能经过若干次生成后让整个矩形上所有格子都有点
n,m<=2e5,q<=min(n*m,2e5)
C
给你n个地点,如果某个地点比两边严格高那么就可以建一座房子
你可以花1的代价让某个地点高度-1,可以减到负
问建造1,2....n/2(上取整)个房子的最少代价分别为多少
n<=5000
D
给你两个字符串s和t,仅有ab两个字符
每次你可以选字符串s的一个前缀(可以是空,可以是全部,t的也一样),和t的一个前缀,然后交换它们
问最少多少次操作可以把a和b完全区分(也就是得到一个纯a字符串和一个纯b字符串),并且给出方案
保证s和t之中至少有一个串包含至少一个a,至少一个串包含至少一个b
字符串长度1<=|s|,|t|<=2e5
===================================
做法:
A
也就是说,把2n个数字分成两组每组n个
让每组最大-最小,乘起来就是答案
那么排序,要么是前后两组1...n n+1...2n
要么1和n一组,中间选一段
复杂度O(n log n)
B
并查集
每行每列都当一个点,每个(x,y)看成第x行到第y列连边
复杂度O(n+m)
C
直接dp
dp(i,j,0/1/2)表示到第i个位置,一共建了j个房子的最小代价
0表示这个点是正常的
1表示这个点是房子
2表示这个点因为房子被削低过
D
特别感谢@wavator造数据帮我调出这题!
人类智慧题
首先连续的可以缩为一个
考虑两个情况
abababab...
abababab...
我们可以每次换长的ab和短的a
那么例如ababab和ab
那么会这样
ababab
ab
-->
aabab
abb
-->
abab
ab
等于长的那个长度-2
直到长度都为2或者有一个为1有一个位2为止
然后直接做
======================
另一个情况是
ababab...
ba....
这样的情况
那么每次我们交换前面的a和b
那么就例如
ababa
bab
就变成了
ababa
bab
-->
bbaba
aab
-->
baba
ab
等于各删去一位
但是要求第二个是2位以上,如果只有一位就没有效果,这个我们底下会提到
=====================
还有一个情况是一位和另一个长串(2位以上)
那么把长串折半下来
例如abababab-->abab换出来
然后如果是a,我们换出来
也就是abababab a --> aabab abab
如果是b,我们留着
也就是abababab b --> abab ababb
=====================
我们还有一种变化方法,感谢wavator提供这个方面的数据
我们上述方法总会把一个串变化到一位,然后执行操作
如果ab babab的串我们就需要更多步
ab babab --> b abab --> ab ab -->b ab --> a b
一共4步
但是
ab babab --> babb aab ( bab ab ) --> ab b --> b a
一共3步
我们可以在当一个长度为2的时候做补救
如果长度<=4,那么补救没有效果
不然的话,这个补救可以让答案-1
也就是执行上述操作
=====================
综上,这题我写了7K
其实有不少可以简化的
比如上来第一步折半处理就好
不过总归做出来了....
=====================
A
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<time.h> #include<math.h> #include<memory> #include<vector> #include<bitset> #include<fstream> #include<stdio.h> #include<utility> #include<string.h> #include<iostream> #include<stdlib.h> #include<algorithm> using namespace std; int a[1000005]; int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int n; scanf("%d",&n); int i; for (i=0;i<2*n;i++) { scanf("%d",&a[i]); } sort(a,a+n+n); long long ans=(long long)(a[n-1]-a[0])*(a[n+n-1]-a[n]); for (i=0;i<=n;i++) { ans=min(ans,(long long)(a[n+n-1]-a[0])*(a[i+n-1]-a[i])); } cout<<ans<<endl; return 0; }
B
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<time.h> #include<math.h> #include<memory> #include<vector> #include<bitset> #include<fstream> #include<stdio.h> #include<utility> #include<string.h> #include<iostream> #include<stdlib.h> #include<algorithm> using namespace std; int fa[1000005]; int size[400005]; int findroot(int x) { int root; for (root=x;fa[root]!=-1;root=fa[root]) ; int temp; for (;fa[x]!=-1;) { temp=fa[x]; fa[x]=root; x=temp; } return root; } void u(int x,int y) { x=findroot(x); y=findroot(y); if (x==y) return; if (size[x]>size[y]) swap(x,y); fa[x]=y; size[y]+=size[x]; } int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int n,m; scanf("%d%d",&n,&m); int q; scanf("%d",&q); int i; for (i=0;i<n+m;i++) { fa[i]=-1; size[i]=1; } for (i=0;i<q;i++) { int x,y; scanf("%d%d",&x,&y); x--; y--; u(x,y+n); } int sum=-1; for (i=0;i<n+m;i++) { if (fa[i]==-1) sum++; } printf("%d ",sum); return 0; }
C
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<time.h> #include<math.h> #include<memory> #include<vector> #include<bitset> #include<fstream> #include<stdio.h> #include<utility> #include<string.h> #include<iostream> #include<stdlib.h> #include<algorithm> using namespace std; int dp[5005][2505][3]; int a[5005]; const int inf=1999999999; //dp [i][j][0] : normal //dp [i][j][1] : Hill //do [i][j][2] : Being Killed inline int min(int x,int y,int z) { return min(min(x,y),z); } int ans[5005]; int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int n; scanf("%d",&n); int i; for (i=1;i<=n;i++) { scanf("%d",&a[i]); } a[0]=-1; a[n+1]=-1; int j,k; for (i=0;i<=n;i++) { for (j=0;j<=(n+1)/2;j++) { for (k=0;k<3;k++) { dp[i][j][k]=inf; } } ans[i]=inf; } dp[0][0][0]=0; for (i=1;i<=n;i++) { for (j=0;j<=(i+1)/2;j++) { dp[i][j][0]=min(dp[i-1][j][0],dp[i-1][j][1],dp[i-1][j][2]); if (i==1) { dp[i][j][1]=max(0,a[2]-(a[1]-1)); } else { dp[i][j][1]=max(0,a[i+1]-(a[i]-1))+min(max(0,a[i-1]-(a[i]-1))+dp[i-1][j-1][0],max(0,min(a[i-1],a[i-2]-1)-(a[i]-1))+dp[i-1][j-1][2]); } ans[j]=min(ans[j],dp[i][j][1]); dp[i][j][2]=dp[i-1][j][1]; } } for (i=1;i<=(n+1)/2;i++) { printf("%d ",ans[i]); } return 0; }
D
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<time.h> #include<math.h> #include<memory> #include<vector> #include<bitset> #include<fstream> #include<stdio.h> #include<utility> #include<string.h> #include<iostream> #include<stdlib.h> #include<algorithm> using namespace std; int get_s[200005]; int get_t[200005]; vector<pair<int,int> > oper; int again_s[200005]; int again_t[200005]; void calc(char s,char t,int cnt_s,int cnt_t) { int now_s=0,now_t=0; int i; for (;;) { if ((now_s+1>=cnt_s)&&(now_t+1>=cnt_t)) { return; } if (now_s+1==cnt_s) { int k=0; int temp=(cnt_t-now_t)/2; memset(again_s,0,sizeof(again_s)); memset(again_t,0,sizeof(again_t)); for (i=0;i<temp;i++) { k+=get_t[now_t]; again_s[i]=get_t[now_t]; now_t++; } int p; char kk=‘b‘; if (temp%2==0) { kk=‘a‘; } bool te=temp%2; if (s!=t) te^=1; if (te) { again_s[temp-1]+=get_s[now_s]; p=0; } else { again_t[0]+=get_s[now_s]; p=get_s[now_s]; } oper.push_back(make_pair(p,k)); int new_cnt_s=temp; int new_cnt_t=0; for (;;) { again_t[new_cnt_t++]+=get_t[now_t++]; if (now_t==cnt_t) break; } memcpy(get_s,again_s,sizeof(get_s)); memcpy(get_t,again_t,sizeof(get_t)); calc(‘a‘,kk,new_cnt_s,new_cnt_t); return; } else if (now_t+1==cnt_t) { int k=0; int temp=(cnt_s-now_s)/2; memset(again_s,0,sizeof(again_s)); memset(again_t,0,sizeof(again_t)); for (i=0;i<temp;i++) { k+=get_s[now_s]; again_t[i]=get_s[now_s]; now_s++; } int p; char kk=‘b‘; if (temp%2==0) { kk=‘a‘; } bool te=temp%2; if (s!=t) te^=1; if (te) { again_t[temp-1]+=get_t[now_t]; p=0; } else { again_s[0]+=get_t[now_t]; p=get_t[now_t]; } oper.push_back(make_pair(k,p)); int new_cnt_t=temp; int new_cnt_s=0; for (;;) { again_s[new_cnt_s++]+=get_s[now_s++]; if (now_s==cnt_s) break; } memcpy(get_s,again_s,sizeof(get_s)); memcpy(get_t,again_t,sizeof(get_t)); calc(‘a‘,kk,new_cnt_s,new_cnt_t); return; } else if (s!=t) { if (cnt_s-now_s==2) { if (cnt_t-now_t>=5) { if (cnt_s==2) { cnt_s=3; get_s[2]=get_s[1]; get_s[1]=get_s[0]; get_s[0]=0; now_s=1; } oper.push_back(make_pair(get_s[now_s],get_t[now_t]+get_t[now_t+1]+get_t[now_t+2])); get_s[now_s+1]+=get_t[now_t+2]; get_t[now_t+3]+=get_s[now_s]; get_s[now_s]=get_t[now_t+1]; get_s[now_s-1]=get_t[now_t]; now_t+=3; now_s--; } } else if (cnt_t-now_t==2) { if (cnt_s-now_s>=5) { if (cnt_t==2) { cnt_t=3; get_t[2]=get_t[1]; get_t[1]=get_t[0]; get_t[0]=0; now_t=1; } oper.push_back(make_pair(get_s[now_s]+get_s[now_s+1]+get_s[now_s+2],get_t[now_t])); get_t[now_t+1]+=get_s[now_s+2]; get_s[now_s+3]+=get_t[now_t]; get_t[now_t]=get_s[now_s+1]; get_t[now_t-1]=get_s[now_s]; now_s+=3; now_t--; } } oper.push_back(make_pair(get_s[now_s],get_t[now_t])); get_s[now_s+1]+=get_t[now_t]; get_t[now_t+1]+=get_s[now_s]; now_s++; now_t++; } else { if (cnt_s-now_s>cnt_t-now_t) { oper.push_back(make_pair(get_s[now_s]+get_s[now_s+1],get_t[now_t])); get_t[now_t+1]+=get_s[now_s+1]; get_s[now_s+2]+=get_t[now_t]; get_t[now_t]=get_s[now_s]; now_s+=2; } else { if (cnt_t-now_t==2) { oper.push_back(make_pair(0,get_t[now_t])); get_s[now_s]+=get_t[now_t]; now_t++; t=‘-‘; } else { oper.push_back(make_pair(get_s[now_s],get_t[now_t]+get_t[now_t+1])); get_s[now_s+1]+=get_t[now_t+1]; get_t[now_t+2]+=get_s[now_s]; get_s[now_s]=get_t[now_t]; now_t+=2; } } } } } int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif ios::sync_with_stdio(false); string s,t; cin>>s>>t; int i; char last_c=‘-‘; int cnt_s=-1; for (i=0;i<(int)s.size();i++) { if (s[i]==last_c) { get_s[cnt_s]++; } else { cnt_s++; get_s[cnt_s]++; last_c=s[i]; } } cnt_s++; last_c=‘-‘; int cnt_t=-1; for (i=0;i<(int)t.size();i++) { if (t[i]==last_c) { get_t[cnt_t]++; } else { cnt_t++; get_t[cnt_t]++; last_c=t[i]; } } cnt_t++; calc(s[0],t[0],cnt_s,cnt_t); printf("%d ",(int)oper.size()); for (i=0;i<(int)oper.size();i++) { printf("%d %d ",oper[i].first,oper[i].second); } return 0; }
以上是关于Codeforces Round #500 (Div.1)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #500 (Div. 2) BC
Codeforces Round#500 Div.2 翻车记