• CF1237H. Balanced Reversals


    题目大意

    给出长为n(n是偶数)的01串S,每次可以把一个长度为偶数的前缀翻转,构造至多n+1次操作把串S变成串T或输出无解

    n<=4000

    题解

    讲杂题时并没有给出操作次数限制,所以以为可以乱做,想每次翻到末尾,这样是3/2n次

    首先把两个合成一组,如果01+10、00、11的个数不相等就无解

    然后考虑从头开始构造,维护一段前缀[1,i]使得rev(S[1,i])=T[1,i],接着每次用两次操作即可把后面的某个接到前面来,最后再把[1,n-2]翻转即可得到T,过程中由于翻了两次所以01和10不会变

    问题是使一开始的01和10个数相等,找到ST中0110差绝对值较大者,将其的一个前缀翻转

    因为差的绝对值越大说明01的个数越靠近0或n/2,反过来的过程中一定会与另一个相遇

    总操作次数为2(n/2-1)+1+1=n

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define abs(x) ((x)>0?(x):-(x))
    #define ll long long
    //#define file
    using namespace std;
    
    int a[4001],b[4001],sum[4],Sum[4],Q,n,N,i,j,k,l,Ls,tot;
    int ans[4002];
    char S[4001],T[4001];
    
    void swap(int &x,int &y) {int z=x;x=y;y=z;}
    int turn(char a,char b) {if (a==b) {return (a=='0')?2:3;} if (a=='0') return 0;return 1;}
    void rev(int *a,int t)
    {
    	int i;
    	fd(i,t/2,1) swap(a[i],a[t-i+1]);
    	fo(i,1,t) if (a[i]<=1) a[i]^=1;
    }
    
    int main()
    {
    	#ifdef file
    	freopen("CF1237H.in","r",stdin);
    	#endif
    	
    	scanf("%d",&Q);
    	for (;Q;--Q)
    	{
    		scanf("%s",S+1),scanf("%s",T+1);
    		n=strlen(S+1),tot=0,N=n/2;
    		memset(sum,0,sizeof(sum));
    		memset(Sum,0,sizeof(Sum));
    		fo(i,1,N) a[i]=turn(S[i*2-1],S[i*2]),++sum[a[i]];
    		fo(i,1,N) b[i]=turn(T[i*2-1],T[i*2]),++Sum[b[i]];
    		if (sum[0]+sum[1]!=sum[0]+sum[1] || sum[2]!=Sum[2] || sum[3]!=Sum[3]) {printf("-1
    ");continue;}
    		
    		Ls=-1,tot=0;
    		if (sum[0]!=Sum[0])
    		{
    			if (abs(sum[0]-sum[1])>abs(Sum[0]-Sum[1]))
    			{
    				fo(i,1,N)
    				if (a[i]<=1)
    				{
    					--sum[a[i]],++sum[a[i]^1];
    					if (sum[0]==Sum[0]) {rev(a,i);ans[++tot]=i;break;}
    				}
    			}
    			else
    			{
    				fo(i,1,N)
    				if (b[i]<=1)
    				{
    					--Sum[b[i]],++Sum[b[i]^1];
    					if (sum[0]==Sum[0]) {rev(b,i);Ls=i;break;}
    				}
    			}
    		}
    		
    		fo(i,1,N-1)
    		{
    			fo(j,i,N)
    			if (a[j]==b[i])
    			{
    				if (j>1) rev(a,j-1),ans[++tot]=j-1;
    				rev(a,j),ans[++tot]=j;
    				break;
    			}
    		}
    		if (N>1) rev(a,N-1),ans[++tot]=N-1;
    		
    		if (Ls>-1) ans[++tot]=Ls;
    		printf("%d
    ",tot);
    		fo(i,1,tot) printf("%d ",ans[i]*2);
    		printf("
    ");
    	}
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    超定方程组
    单应矩阵
    Flexible Camera Calibration By Viewing a Plane From Unknown Orientations
    解 Ax = 0
    PVANET: Deep but Lightweight Neural Networks for Real-time Object Detection
    图像处理库
    visdom 简单使用
    STN(Spatial Transformer Networks)
    Distilling the Knowledge in a Neural Network
    记一次前端中国标准时间转换为yyyy-MM-dd类型
  • 原文地址:https://www.cnblogs.com/gmh77/p/14026671.html
Copyright © 2020-2023  润新知