zoukankan      html  css  js  c++  java
  • Codeforces Round #663 (Div. 2)

    A. Suborrays

    题解

    构造一个序列使得任意区间按位或的答案大于等于区间长度,打个表发现好像啥都行,于是就瞎输出了

    #include<bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef long long LL;
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    int T,n;
    int main()
    {
    	T=read();
    	while(T--)
    	{
    		n=read();
    		for(int i=1;i<n;i++)printf("%d ",i);
    		printf("%d
    ",n);
    	}
    	return 0;
    }
    

    B. Fix You

    题解

    一开始读错题了以为LRUD都有,结果发现只有RD,于是就只需要判下面是不是都是R,右边是不是都是D就好了

    #include<bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef long long LL;
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    int n,m,a[110][110];
    char pic[110][110];
    bool vis[110][110];
    bool legal(int x,int y)
    {
    	return (x>=0 && x<n) && (y>=0 && y<m);
    }
    queue<PII> Q;
    int main()
    {
    	for(int T=read();T;T--)
    	{
    		n=read();m=read();
    		for(int i=0;i<n;i++)for(int j=0;j<m;j++)vis[i][j]=a[i][j]=0;
    		for(int i=0;i<n;i++)scanf("%s",pic[i]);
    		int cnt=0;
    		for(int i=0;i<m-1;i++)if(pic[n-1][i]!='R')cnt++;
    		for(int i=0;i<n-1;i++)if(pic[i][m-1]!='D')cnt++;
    		printf("%d
    ",cnt);
    	}
    	return 0;
    }
    

    C. Cyclic Permutations

    题解

    题目花里胡哨的说了一坨,反正推了一下发现满足题意的就是这个序列需要有一个谷底,那么我们反其道行之,求不存在谷底的排列有多少就行,设峰值(n)(i) 位置,那么我们剩下(n-1)个数就已经按顺序拍好了,有(C_{n-1}^{i-1}) 种方案,最后用(n!) 减去(sum_{i=0}^{n-1} C_{n-1}^i) 即可,(其实那玩意就是(2_{n-1}) 没有发现)

    #include<bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef long long LL;
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    const int MOD=1000000007,maxn=1000010;
    int n;
    LL fac=1,inv[maxn],C[maxn],ans; 
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;i++)fac=(fac*i)%MOD;	
    	inv[1]=1;
    	for(int i=2;i<=n;i++)inv[i]=((MOD-MOD/i)*inv[MOD%i])%MOD;
    	C[0]=1;
    	for(int i=1;i<=n-1;i++)C[i]=(C[i-1]*LL(n-i))%MOD*inv[i]%MOD;
    	for(int i=1;i<=n;i++)ans=(ans+C[i-1])%MOD;
    	printf("%lld
    ",((fac-ans)%MOD+MOD)%MOD);
    	return 0;
    }
    
    

    D. 505

    题解

    题目大意是给你一个01矩阵,问最少修改多少个数,使得这个矩阵的所有偶数边长的子正方形矩阵里面都有奇数个1。
    很容易发现,当(n>3)的时候,存在一个(4*4) 的矩阵,里面还包含着4个(2*2) 的矩阵,这个肯定是矛盾的,所以就只讨论(n<4) 的情况。
    (n=1) 的时候答案是0, 当(n=2或者n=3) 的时候就状压DP设(dp[i][s]) 表示当前在第(i) 列,第(i) 列的01摆法为S就可以了,复杂度是(O(4*4*n/2)或者O(8*8*n/6))

    #include<bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef long long LL;
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    const int maxn=1000010,inf=maxn;
    int n,m,a[4][maxn],dp[maxn][2][2],DP[maxn][8];
    char s[4][maxn];
    int main()
    {
    	n=read();m=read();
    	if(n>=4)return puts("-1"),0;
    	if(n==1)return puts("0"),0;
    	for(int i=0;i<n;i++)scanf("%s",s[i]);
    		for(int i=0;i<n;i++)
    			for(int j=0;j<m;j++)a[i][j]=s[i][j]-'0';
    	if(n==2)
    	{
    		for(int i=0;i<m;i++)dp[i][0][0]=dp[i][0][1]=dp[i][1][0]=dp[i][1][1]=inf;
    		for(int i=0;i<2;i++)
    			for(int j=0;j<2;j++)
    				if(a[0][0]==i && a[1][0]==j)dp[0][i][j]=0;
    				else dp[0][i][j]=1;
    		for(int i=1;i<m;i++)
    		{
    			for(int jj=0;jj<2;jj++)
    				for(int kk=0;kk<2;kk++)
    				{
    					int cnt=2;
    					if(a[0][i]==jj)cnt--;
    					if(a[1][i]==kk)cnt--;
    					for(int j=0;j<2;j++)
    						for(int k=0;k<2;k++)
    							if((j+k+jj+kk)%2)dp[i][jj][kk]=min(dp[i][jj][kk],dp[i-1][j][k]+cnt);
    				}
    		}
    		int ans=maxn;
    		for(int i=0;i<2;i++)for(int j=0;j<2;j++)ans=min(ans,dp[m-1][i][j]);
    		printf("%d
    ",ans);
    		return 0;
    	}
    	if(n==3)
    	{
    		for(int i=0;i<m;i++)for(int j=0;j<8;j++)DP[i][j]=inf;
    		for(int i=0;i<8;i++)
    		{
    			int S1=i&1,S2=(i>>1)&1,S3=(i>>2)&1;
    			int cnt=3;
    			if(a[0][0]==S1)cnt--;
    			if(a[1][0]==S2)cnt--;
    			if(a[2][0]==S3)cnt--;
    			DP[0][i]=cnt;
    		}
    		for(int i=1;i<m;i++)
    		{
    			for(int S=0;S<8;S++)
    			{
    				int S1=S&1,S2=(S>>1)&1,S3=(S>>2)&1;
    //				printf("%d %d%d%d
    ",S,S1,S2,S3);
    				int cnt=3;
    				if(a[0][i]==S1)cnt--;
    				if(a[1][i]==S2)cnt--;
    				if(a[2][i]==S3)cnt--;
    				for(int s=0;s<8;s++)
    				{
    					int s1=s&1,s2=(s>>1)&1,s3=(s>>2)&1;
    //					if(i==1 && S==6)printf("%d %d %d %d %d %d
    ",s1,s2,s3,S1,S2,S3);
    					if((S1+s1+S2+s2)%2 && (S2+s2+S3+s3)%2)DP[i][S]=min(DP[i][S],DP[i-1][s]+cnt);
    				}
    //				printf("%d %d %d
    ",i,S,DP[i][S]);
    			}
    		}
    //		for(int i=0;i<m;i++)for(int S=0;S<8;S++)printf("%d %d %d
    ",i,S,DP[i][S]);
    		int ans=maxn;
    		for(int i=0;i<8;i++)ans=min(ans,DP[m-1][i]);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    E. Pairs of Pairs

    题解

    又是一道很诡异的题,题目大意是给你一个无向图,你要不在图中找到一个长度大于等于(lceil frac{n}{2} ceil) 的简单路径,要不就找若干个二元组(其中这些二元组的元素不能重复,至少要多于等于(lceil frac{n}{2} ceil) ),使得任意两个二元组组成的子图,至多有两条边。
    直接看了题解,题解是随便找一点开始求他的dfs树,如果dfs树中有深度大于等于(lceil frac{n}{2} ceil) 的点,就直接输出即可,否则就找所有深度相同的点,两两配对,一定能保证配出(lceil frac{n}{4} ceil) 对。怎么证明呢?
    先证这任意两个二元组组成的子图吧,根据dfs树的性质,所有非树边一定是祖先连往子孙,不可能存在子树之间的连边 ,深度相同的点显然是属于两个子树,所以保证两个二元组((a,b),(c,d)) 其中(deep[a]=deep[b],deep[c]=deep[d])(deep[a]<deep[c]),a和b 不可能连边,c和d不可能连边,那两条边只可能是a和c,b和d为父子关系的时候才可以算上。
    再证一定大于(lceil frac{n}{4} ceil) 对,因为不存在深度大于(lceil frac{n}{2} ceil) 了,所以最大深度不过(lceil frac{n}{2} ceil) ,每一个深度只有当有0个或者1个节点的时候才会放弃这个深度,根据抽屉原理一定能选出(lceil frac{n}{4} ceil) 对满足。

    #include<bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef long long LL;
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    const int maxn=500010,maxm=1000010;
    int n,m,a,b,deep[maxn],pa[maxn],max_deep;
    vector<int> G[maxn],deep_pair[maxn];
    bool path,vis[maxn];
    void dfs(int now,int fa)
    {
    	vis[now]=1;
    	pa[now]=fa;
    	if(path)return;
    	deep_pair[deep[now]].push_back(now);
    	max_deep=max(max_deep,deep[now]);
    	if(deep[now]>=(n+1)/2)
    	{
    		int tmp=now;
    		printf("PATH
    %d
    ",deep[now]);
    		while(tmp!=1)printf("%d ",tmp),tmp=pa[tmp];
    		puts("1");
    		path=1;
    		return;
    	}
    	for(int v:G[now])
    		if(v!=fa && !vis[v])
    			deep[v]=deep[now]+1,dfs(v,now);
    }
    int main()
    {
    	for(int T=read();T;T--)
    	{
    		n=read();m=read();
    		max_deep=path=0;
    		for(int i=1;i<=n;i++)G[i].clear(),vis[i]=0;
    		for(int i=1;i<=m;i++)a=read(),b=read(),G[a].push_back(b),G[b].push_back(a);
    		deep[1]=1; 
    		dfs(1,0);
    		if(!path)
    		{
    			int cnt=0;
    			for(int i=2;i<=max_deep;i++)cnt+=deep_pair[i].size()/2;
    			printf("PAIRING
    %d
    ",cnt);
    //			for(int i=1;i<=max_deep;i++)
    //			{
    //				printf("deep %d:",i);
    //				for(int j=0;j<deep_pair[i].size();j++)printf("%d ",deep_pair[i][j]);
    //				puts("");
    //			}
    			for(int i=2;i<=max_deep;i++)
    			{
    				for(int j=0;j+1<deep_pair[i].size();j+=2)printf("%d %d
    ",deep_pair[i][j],deep_pair[i][j+1]);
    			}
    		}
    		for(int i=1;i<=max_deep;i++)deep_pair[i].clear();
    	} 
    	return 0;
    }
    
    

    废话

  • 相关阅读:
    观察者与被观察者
    Gson和阿里的JSON简单对比
    银行卡输入特效 4个加一空格
    Android 点击空白处蕴藏键盘
    Android覆盖安装及常遇到的问题
    Android view中的requestLayout和invalidate方法
    医药行业GSP注册流程
    如何快速查询视图
    反写规则超额控制
    预算管理的操作步骤
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/13480766.html
Copyright © 2011-2022 走看看