zoukankan      html  css  js  c++  java
  • CF1257E/F

    E

    给出三个序列共n个元素,每个元素值为1~n且不重

    一次可以把一个元素换到另一个序列中,求最少操作次数使得三个序列(可为空)分别排序后并在一起为1~n顺序

    题解

    (伪)神仙题

    随便dp,依次考虑每个数放在那里

    由于要保证最终的顺序,所以放的序列的编号要单调

    f[i][0/1/2],第i个放在0/1/2的最小操作数

    code

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define min(a,b) (a<b?a:b)
    using namespace std;
    
    int a[200002];
    int f[200002][3];
    int n,n1,n2,n3,i,j,k,l,ans,Ans;
    
    int main()
    {
    //	freopen("e.in","r",stdin);
    	
    	scanf("%d%d%d",&n1,&n2,&n3);n=n1+n2+n3;
    	fo(i,1,n1) scanf("%d",&j),a[j]=0;
    	fo(i,1,n2) scanf("%d",&j),a[j]=1;
    	fo(i,1,n3) scanf("%d",&j),a[j]=2;
    	
    	memset(f,127,sizeof(f));
    	
    	f[0][0]=f[0][1]=f[0][2]=0;
    	fo(i,0,n-1)
    	{
    		fo(j,0,2)
    		{
    			fo(k,j,2)
    			f[i+1][k]=min(f[i+1][k],f[i][j]+(k!=a[i+1]));
    		}
    	}
    	
    	printf("%d
    ",min(min(f[n][0],f[n][1]),f[n][2]));
    }
    

    F

    n个数,求一个x(x<=2^30-1)使得每个ai xor x二进制下一的个数相同

    ai<=2^30-1

    题解

    折半,每边15位

    设n个数最终1的个数为x,i的前15位异或后1的个数为ci

    那么后15位的个数分别为x-c1,x-c2,x-c3...x-cn

    差分一下变成c1-c2,c2-c3,c3-c4...,刚好与前15位的差分c2-c1,c3-c2,c4-c3...成相反数关系

    处理出一边的情况,把序列取反哈希后丢到map里,再枚举另一边判断即可

    code

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <map>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define mod 1145141919810ll
    using namespace std;
    
    int a[101];
    int b[101];
    int n,i,j,k,l,x,s1,s2;
    map<long long,int> hs;
    map<long long,int> :: iterator I;
    long long s;
    
    int get(int x)
    {
    	int s=0;
    	
    	while (x)
    	{
    		++s;
    		x^=x&-x;
    	}
    	
    	return s;
    }
    
    int main()
    {
    //	freopen("f.in","r",stdin);
    	
    	scanf("%d",&n);
    	fo(i,1,n)
    	scanf("%d",&a[i]),b[i]=a[i]&32767,a[i]=a[i]>>15;
    	
    	fo(x,0,32767)
    	{
    		s=1;
    		fo(i,1,n)
    		{
    			s1=get(a[i]^x);
    			
    			if (i>1)
    			s=(s*233+(s1-s2+233))%mod;
    			
    			s2=s1;
    		}
    		
    		hs.insert(map<long long,int>::value_type(s,x));
    	}
    	
    	fo(x,0,32767)
    	{
    		s=1;
    		fo(i,1,n)
    		{
    			s1=get(b[i]^x);
    			
    			if (i>1)
    			s=(s*233+(s2-s1+233))%mod;
    			
    			s2=s1;
    		}
    		
    		I=hs.find(s);
    		if (I!=hs.end())
    		{
    			printf("%d
    ",(*I).second*32768+x);
    			return 0;
    		}
    	}
    	
    	printf("-1
    ");
    }
    
  • 相关阅读:
    递推2 2046
    递推思想
    acm2047
    杭电ACM2043
    判断a=b?
    将一列字段用逗号分隔开,作为一个显示
    MESQL 数据误操作,恢复数据方法
    有两个frame,在一个frame中获取另一个frame中元素的值
    饼状图显示各类别展示所占百分比
    winfrom中的webbrowser内核版本修改
  • 原文地址:https://www.cnblogs.com/gmh77/p/11864302.html
Copyright © 2011-2022 走看看