zoukankan      html  css  js  c++  java
  • Comet OJ


    B

    整个表格其实是一些联通块,取反操作不能跨连通块。所以直接统计一下每个连通块内数字不对的个数是不是偶数即可


    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define gt(x,y) ((x)*m+y)
    using namespace std;
    
    const int M = 1100000;
    int n,m,k,a[M],b[M],d[M],T,r,c,cnt=0,s[M];
    char C[M];
    bool check(int x,int y)
    {
    	if(x<0 || y<0 || x>=n || y>=m) return 0;
    	return 1;
    }
    
    void dfs(int x,int y)
    {
    	if(!check(x,y)) return ;
    	if(d[gt(x,y)]) return ;
    	d[gt(x,y)]=cnt;
    	dfs(x-r,y); dfs(x+r,y); dfs(x,y-c); dfs(x,y+c);
    }
    
    int main()
    {
    	scanf("%d",&T);
    	for(;T;T--)
    	{
    		scanf("%d%d%d%d",&n,&m,&r,&c);
    		int B=1; cnt=0;
    		for(int i=0;i<n;i++)
    			for(int j=0;j<m;j++) if(!d[gt(i,j)])
    			{
    				cnt++; dfs(i,j);
    			}
    		for(int i=0;i<n;i++)
    		{
    			scanf("
    %s",C);
    			for(int j=0;j<m;j++) a[gt(i,j)]=C[j]-'0';
    		}
    		for(int i=0;i<n;i++)
    		{
    			scanf("
    %s",C);
    			for(int j=0;j<m;j++) 
    			{
    				k=C[j]-'0';
    				if(k!=a[gt(i,j)]) s[d[gt(i,j)]]^=1;
    			}
    		}
    		for(int i=1;i<=cnt;i++) if(s[i]) B=0;
    		if(B) printf("Yes
    ");
    		else printf("No
    ");
    		for(int i=0;i<=n*m;i++) a[i]=b[i]=d[i]=s[i]=0; 
    	}
    }
    

    C

    直接建图跑最短路

    注意注意注意 :如果在某一车站有两辆公交车同事进站,他们之间要连双向边!


    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #define gt(x,y) ((x)*m+y)
    using namespace std;
    
    const int M = 2100000;
    int t,m,k,b[M],d[M],T,cnt=0,n1,n2,s,t1,t2,head[M],nex[M*3],edge[M*3],ver[M*3],S;
    priority_queue<pair<int,int> >q;
    struct vv
    {
    	int a,b;
    } v[M];
    
    bool cmp(vv a,vv b){return a.a<b.a;}
    
    void add(int x,int y,int z)
    {
    	ver[++cnt]=y, nex[cnt]=head[x], head[x]=cnt; edge[cnt]=z;
    }
    
    void dj()
    {
    	for(int i=0;i<=t;i++) d[i]=0x3f3f3f3f, b[i]=0;
        while(q.size()) q.pop(); d[S]=0;
        q.push(make_pair(0,S));
        while(q.size())
        {
            while(q.size() &&(b[q.top().second])) q.pop();
            if(!q.size()) break;
            int x=q.top().second; q.pop(); b[x]=1; 
            for(int i=head[x];i;i=nex[i])
            {
                int t=ver[i];
                if(d[x]+edge[i]<d[t]) 
                {
                    d[t]=d[x]+edge[i];
                    q.push(make_pair(-d[t],t));
                }
            }
        }
    }
    
    int main()
    {
    	scanf("%d",&T);
    	for(;T;T--)
    	{
    		scanf("%d%d%d%d%d%d",&m,&n1,&n2,&s,&t1,&t2);
    		
    		t=m*(n1+n2)+2; S=t-1;  cnt=0;
    		for(int i=0;i<m;i++)
    		{
    			for(int j=0;j<n1+n2;j++) scanf("%d",&v[j].a), v[j].b=j;			
    			sort(v,v+n1+n2,cmp);
    			for(int j=0;j<n1+n2-1;j++) 
    			{
    				add(gt(v[j].b,i),gt(v[j+1].b,i),v[j+1].a-v[j].a);
    				if(v[j+1].a==v[j].a) add(gt(v[j+1].b,i),gt(v[j].b,i),v[j+1].a-v[j].a);
    			}
    			if(i)
    			{				
    				for(int j=0;j<n1;j++) add(gt(j,i-1),gt(j,i),0);
    				for(int j=0;j<n2;j++) add(gt(n1+j,i),gt(n1+j,i-1),0); 
    			}
    			if(i!=s-1) continue;
    			for(int j=0;j<n1+n2;j++) if(v[j].a>=t1 && v[j].a<=t2) add(S,gt(v[j].b,i),v[j].a-t1);
    			for(int j=0;j<n1+n2;j++) if(v[j].a>=t1 && v[j].a<=t2) add(gt(v[j].b,i),t,t2-v[j].a);
    		}
    		dj();
    		printf("%d
    ",min(d[t],t2-t1));
    		for(int i=0;i<=cnt;i++) edge[i]=ver[i]=nex[i]=0;
    		for(int i=0;i<=t;i++) head[i]=0;
    	}
    }
    

    D

    异或和为n说明这两个数只有在n为1的位上值不同

    也就是说如果n有第i位为1,那么两个数有且仅有一个第i位为1; 否则两个数这一位的取值相同

    然后两数之差又不能超过m,就可以求出最大的n的子集记为g(窝就是这里求错了超时了15s来着

    然后就可以数位dp辣!

    (f[i][A][B][G])表示二进制下的第i位,x是不是a的上限,y是不是b的上限,xy中的哪个或者都没有达到g的上限

    由于没想到什么妙妙的转移方法,我选择手写转移


    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define LL long long 
    using namespace std;
    
    const int M = 100001;
    int T;
    LL n,m,k,f[2][2][2][4],a,b,w,g;
    int main()
    {
    	scanf("%d",&T);
    	for(;T;T--)
    	{
    		scanf("%lld%lld%lld%lld",&a,&b,&n,&m); g=0;
    		LL e=0,S=0;
    		for(int i=60;i>=0;i--) if((1ll<<i)&n)
    		{
    			S+=(1ll<<i);
    			if(e+(1ll<<i)-(n-S)<=m) g+=(1ll<<i), e+=(1ll<<i);
    			else e-=(1ll<<i);
    		}
    		if(n-g>g || e<0) 
    		{
    			printf("0
    ");
    			continue;
    		}
    		for(int i=60;i>=0;i--) if(g&(1ll<<i)) 
    		{
    			w=(1ll<<i);
    			break;
    		}
    		
    		memset(f,0,sizeof(f));
    		f[1][1][1][0]=1ll;
    		for(int i=60;i>=0;i--)
    		{
    			int t=i&1;
    			memset(f[t],0,sizeof(f[t]));
    			LL r=1ll<<i;
    			for(int A=0;A<=1;A++)
    			for(int B=0;B<=1;B++)
    			for(int k=0;k<=2;k++) if(f[!t][A][B][k])
    			{
    				if(n&r)
    				{
    					if(w==r)
    					{
    						int A1=0,B1=0,k1=0;
    						if((A && (a&r))||(!A)) 
    						{
    							int B1=0;
    							if(B && (b&r)==0) B1=1;
    							f[t][A][B1][1]=f[t][A][B1][1]+f[!t][A][B][k];
    						}
    						if((B && (b&r))||(!B)) 
    						{
    							int A1=0;
    							if(A && (a&r)==0) A1=1;
    							f[t][A1][B][2]=f[t][A1][B][2]+f[!t][A][B][k];
    						}
    					}
    					else 
    					{
    						if(((k==1 && (g&r))||k!=1) &&( (A &&(a&r))|| !A))
    						{
    							int k1=0;
    							if(k==2 && ((g&r)==0)) k1=2;
    							if(k==1 && (g&r)) k1=1;
    							int B1=0;
    							if(B && (b&r)==0) B1=1;
    							f[t][A][B1][k1]=f[t][A][B1][k1]+f[!t][A][B][k];
    						}
    						if(((k==2 && (g&r))||k!=2) &&( (B &&(b&r))|| !B))
    						{
    							int k1=0;
    							if(k==1 && ((g&r)==0)) k1=1;
    							if(k==2 && (g&r)) k1=2;
    							int A1=0;
    							if(A && (a&r)==0) A1=1;
    							f[t][A1][B][k1]=f[t][A1][B][k1]+f[!t][A][B][k];
    						}
    					}
    				}
    				else 
    				{
    					int A1=0, B1=0;
    					if(A && (a&r)==0) A1=1;
    					if(B && (b&r)==0) B1=1;
    					f[t][A1][B1][k]=f[t][A1][B1][k]+f[!t][A][B][k];
    						
    					if((A && (a&r)==0) ||(B && (b&r)==0)) continue;
    
    					A1=0, B1=0;
    					if(A && (a&r)) A1=1;
    					if(B && (b&r)) B1=1;
    					f[t][A1][B1][k]=f[t][A1][B1][k]+f[!t][A][B][k];
    				}
    			}
    		}
    		LL res=0;
    		for(int i=0;i<=1;i++)
    		for(int j=0;j<=1;j++)
    		for(int k=0;k<=2;k++) res=res+f[0][i][j][k];
    		printf("%lld
    ",res);
    	}
    }
    
  • 相关阅读:
    PyQt信号传递的方法
    tensorflow 遇到的细节问题
    正则表达式的总结
    ImageFont与PIL
    pytorch源码解析-动态接口宏
    intel windows caffe加速
    cnn可视化 感受野(receptive field)可视化
    Ubuntu安装使用latex
    使用caffe训练mnist数据集
    caffe使用ctrl-c不能保存模型
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/11664732.html
Copyright © 2011-2022 走看看