Codeforces Round #545 (Div. 2)
A. Sushi for Two
题意:给出 只有1 和2 组成的数组 求最大形如xxxyyy的长度
思路:直接扫一边 1 和2 分界的时候记一下分界之前的那个 1或2的连续长度即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+5; 4 int a[maxn]; 5 int main(){ 6 int one=0,two=0; 7 int n; 8 scanf("%d",&n); 9 int ans=0; 10 int flag=0; 11 for(int i=0;i<n;i++)scanf("%d",&a[i]); 12 flag=a[0]; 13 for(int i=0;i<n;i++){ 14 if(flag==1){ 15 if(a[i]==1)one++; 16 else { 17 ans=max(ans,min(one,two)); 18 two=1; 19 flag=2; 20 } 21 } 22 else if(flag==2){ 23 if(a[i]==2)two++; 24 else { 25 ans=max(ans,min(one,two)); 26 one=1; 27 flag=1; 28 } 29 } 30 } 31 ans=max(ans,min(two,one)); 32 cout<<ans*2<<endl; 33 }
B. Circus
题意:每个人可能有两种属性 1表示有0表示没有 则一个人有四种情况 11 10 01 00 让分成两组 (为了叙述方便 前面的数字表示前面的属性,后面的数字表示后面的属性,例如10 前面的属性有,后面的属性无)分组后 要使其中一组的前面一个属性多少个人有等于 后面一组的后面一个属性有多少个人有
思路:
设第一组选了 四种人的数量分别为a(0,0) b(0,1) c(1,0) d(1 1) 总数分别为na nb nc nd
而根据两组的等式关系有 c+d=(nb-b)+(nd-d)
有两个未知数 暴力即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<f_end;i++) 4 #define MT(x,i) memset(x,i,sizeof(x)) 5 #define ll long long 6 #define inf 0x3f3f3f3f 7 vector<int >zero,two,three,one; 8 char a[5000+5],b[5000+5]; 9 int main(){ 10 int n; 11 int na=0,nb=0,nc=0,nd=0; 12 scanf("%d",&n); 13 scanf("%s",a); 14 scanf("%s",b); 15 for(int i=0;i<n;i++){ 16 if(a[i]=='0'&&b[i]=='0')na++,zero.push_back(i+1); 17 else if(a[i]=='0'&&b[i]=='1')nb++,one.push_back(i+1); 18 else if(a[i]=='1'&&b[i]=='0')nc++,two.push_back(i+1); 19 else nd++,three.push_back(i+1); 20 } 21 FOR(a,0,na+1){ 22 FOR(b,0,nb+1){ 23 int c=n-2*(a+b)-nb-nd+b; 24 if(c>=0&&c<=nc){ 25 int d=n/2-c-a-b; 26 if(d>=0&&d<=nd){ 27 FOR(i,0,a){ 28 printf("%d ",zero[i]); 29 } 30 FOR(i,0,b){ 31 printf("%d ",one[i]); 32 } 33 FOR(i,0,c) 34 printf("%d ",two[i]); 35 FOR(i,0,d) 36 printf("%d ",three[i]); 37 return 0; 38 } 39 } 40 } 41 } 42 printf("-1"); 43 return 0; 44 }
C. Skyscrapers
题意 有n*m个房子分布在网格图中 问分别对每一行和每一列的房子进行一下映射 使得每一行的房子高度大小关系不变 并且映射的范围是(1-x)要使x尽可能小 (这里的映射只是针对选定的一个行和列而言 到另外一行重新映射 是互不影响的)
思路:预处理每一行(和每一列)的位置大小 其中相等的可以进行类似合并的操作 最后针对每一个点 他的最小x 为 max(行的大小位置,列的大小位置)+max(行总数-行的大小位置 ,列总数-列的大小位置) 画个图很容易理解
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++) 4 #define MT(x,i) memset(x,i,sizeof(x)) 5 #define inf 0x3f3f3f3f 6 #define mkp make_pair 7 #define all(v) (v).begin(),(v).end() 8 #define F first 9 #define S second 10 #define pii pair<int,int> 11 #define pb push_back 12 const int maxn=1e3+5; 13 int a[maxn][maxn]; 14 int rr[maxn][maxn],cc[maxn][maxn],r[maxn],l[maxn]; 15 int main(){ 16 int n,m ; 17 scanf("%d%d",&n,&m); 18 FOR(i,1,n) 19 FOR(j,1,m)scanf("%d",&a[i][j]); 20 FOR(i,1,n){ 21 vector<pii>v; 22 FOR(j,1,m){ 23 v.pb(mkp(a[i][j],j)); 24 } 25 sort(all(v)); 26 int last=-1,cnt=0; 27 for(pii tmp:v){ 28 if(tmp.F!=last){ 29 cnt++; 30 last=tmp.F; 31 } 32 rr[i][tmp.S]=cnt; 33 } 34 r[i]=cnt; 35 } 36 FOR(i,1,m){ 37 vector<pii>v; 38 FOR(j,1,n){ 39 v.pb(mkp(a[j][i],j)); 40 } 41 sort(all(v)); 42 int last=-1,cnt=0; 43 for(pii tmp:v){ 44 if(tmp.F!=last){ 45 last=tmp.F; 46 cnt++; 47 } 48 cc[tmp.S][i]=cnt; 49 } 50 l[i]=cnt; 51 } 52 FOR(i,1,n){ 53 FOR(j,1,m){ 54 printf("%d ",max(rr[i][j],cc[i][j])+max(r[i]-rr[i][j],l[j]-cc[i][j])); 55 } 56 puts(""); 57 } 58 59 return 0; 60 }
D. Camp Schedule
题意 给出一个串 s 和一个串t(都是01串) 现对s串进行重新排序 使得串t在排序后的串后尽可能多的 出现(可以重叠)
思路:先由 0 1 的数量关系 和串的长度 判断t可不可能在s中出现 然后找出t的最长相等的前缀和后缀(kmp的get_next 不然会超时)之后就由 不在公共前缀和后缀里面的01的数量关系构造即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define FOR(i,f_start,f_end) for(int i=f_start ;i<=f_end;i++) 4 #define MT(x,i) memset(x,i,sizeof(x)) 5 #define inf 0x3f3f3f3f 6 #define mkp make_pair 7 #define all(v) (v).begin(),(v).end() 8 #define F first 9 #define S second 10 #define pii pair<int,int> 11 #define pb push_back 12 const int maxn=5e5+5; 13 char s[maxn],t[maxn]; 14 int Next[maxn]; 15 int get_next(const char *s, int *Next) 16 { 17 int i = 0, j = -1, len = strlen(s); 18 Next[0] = -1; 19 while (i<len) 20 { 21 if (j==-1 || s[i]==s[j]) 22 Next[++i] = ++j; 23 else 24 j = Next[j]; 25 } 26 27 return len; 28 } 29 30 int main(){ 31 scanf("%s%s",s,t); 32 int a1,a2,b1,b2; 33 a1=a2=b1=b2=0; 34 int len1=strlen(s),len2=strlen(t); 35 if(len1<len2){ 36 printf("%s",s); 37 return 0; 38 } 39 FOR(i,0,len1-1){ 40 if(s[i]=='1')a1++; 41 else b1++; 42 } 43 FOR(i,0,len2-1){ 44 if(t[i]=='1')a2++; 45 else b2++; 46 } 47 int suffix=0; 48 get_next(t, Next); 49 suffix = Next[len2]; 50 if(a1>=a2&&b1>=b2){ 51 a1-=a2,b1-=b2; 52 printf("%s",t); 53 int sa=0,sb=0; 54 FOR(i,suffix,len2-1){ 55 if(t[i]=='1')sa++; 56 else sb++; 57 } 58 int tx; 59 if(sa&&sb){ 60 tx=min(a1/sa,b1/sb); 61 } 62 else if(sa&&!sb){ 63 tx=a1/sa; 64 } 65 else if(!sa&&sb){ 66 tx=b1/sb; 67 } 68 a1-=tx*sa,b1-=tx*sb; 69 FOR(i,1,tx)printf("%s",t+suffix); 70 while(a1--)printf("1"); 71 while(b1--)printf("0"); 72 } 73 else { 74 printf("%s",s); 75 } 76 77 return 0; 78 }