Codeforces Round #663 (Div. 2) A-E总题解

Solution

A

由于无论 x x 与谁做或运算,结果均不会小于 x x ;所以,我们只需要输出 1 , 2 , n 1,2,……n ,保证以 x x 结尾与 x x 开头的区间一定满足要求。

B

显然,最终所有的东西都会集中到底部或右侧;此时,我们只需要让最右边一列的字符全为 D D ,底侧的字符全为 R R ,即可满足要求

故答案为右侧 R R 的数量与底侧 D D 的数量之和。

C

显然,最大的数是不会往外连边的,其他的数一定会往外连至少一条边,故至少有 n 1 n-1 条边。

反面考虑。由于有 n n 个顶点,我们要让它不成环,边的数量不能超过 n 1 n-1 ,即必须让该图成为一个树的形态才可以。故只能有 n 1 n-1 条边

尝试构造一些满足"所有值非 n n 的节点向外连边的数量均为 1 1 条"的排列,可以发现,这些排列都是单峰序列。峰左的数向它右边的数连边,峰右的数向它左边的数连边。

于是,现在我们思考如何求出单峰序列的数量。显然,峰值一定为 n n 。可以发现,只要选定了峰左哪些数出现了,那么整个序列都确定下来了。当 n n 被选做峰顶的时候,显然剩下有 n 1 n-1 个数可选;设峰顶的位置为 k k ,则峰左的数有 C n 1 k 1 C_{n-1}^{k-1} 种选择。

故答案为 n ! i = 1 n C n 1 i 1 n!-\sum_{i=1}^n C_{n-1}^{i-1}

这个式子可以进一步优化:

n ! i = 1 n C n 1 i 1 n!-\sum_{i=1}^n C_{n-1}^{i-1}

= n ! 2 n 1 =n!-2^{n-1}

于是,我们只需要使用普通幂与阶乘,并注意减法的取模方式即可通过本题。

时间复杂度 O ( n ) O(n)

D

首先,可以发现,对于一个 4 × 4 4×4 的子矩阵,它是由四个 2 × 2 2×2 的子矩阵组合而成的;而这四个 2 × 2 2×2 的子矩阵各数之和必须都是奇数,故一个 4 × 4 4×4 的子矩阵的各数之和只能是奇数的四倍,即偶数,不符题意。所以,可以推出,如果 n × m n×m 的矩形中含有任何一个 4 × 4 4×4 的子矩阵,均应输出 1 -1 。注意,当一个长方形含有 4 × 4 4×4 的子矩阵时,当且仅当 n , m 4 n,m≥4

此时,我们的长方形的长度为 n n ,宽度为 m m ,必有 n 4 n<4 m 4 m<4 。不妨设 n m n≥m ,即 m 4 m<4 ,显然这时长方形是一条宽度为 1 1 2 2 3 3 的链。

于是,我们考虑状压 d p dp 。由于每一行的状态并不多(最多 8 8 个),可以考虑用一个压位十进制数表示每一位的状态,并暴力转移即可。注意,此时我们只需要保证任何 2 × 2 2×2 的子矩阵中和为奇数,其他并无限制

总时间复杂度为 O ( k n m ) O(knm) ,其中 k k 是一个巨大的常数,但是并不妨碍我们 A C AC 本题。

E

比赛场上脑子瓦特, E E 没做出来QAQ

本题做法十分简单。首先,我们从 1 1 号节点对整个图进行深搜,得到了每个节点的深度。对于第一个问题而言,如果有节点的深度达到了 n 2 \lceil \frac n 2 \rceil ,则直接递归打印该路径。

如果没达到呢?我们不得不开始思考问题 2 2 。并不显然地发现,对于同深度的节点两两配对即可

为什么呢?首先,由于它们是同深度的,它们之间不会有边。同时,对于 p a i r ( a , b ) pair(a,b) p a i r ( c , d ) pair(c,d) (不妨设 a , b a,b 的深度小于 c , d c,d 的深度)不可能出现 ( a , b , c , d ) (a,b,c,d) 形成一个独立的连通图的情况。因为若形成连通图,不可能满足 a a b b 属于同一深度且 c c d d 属于同一深度,因为搜到 a a 的时候, a a 直接把另外三个点给全部搜了一遍。

所以,这种做法是正确的。

比赛的时候想到了不会证明不敢写QAQ

Code

A

#include <bits/stdc++.h>
#define int long long
using namespace std;

int t,n;
int a[200005];

signed main()
{
	cin>>t;
	while (t--)
	{
		cin>>n;
		for (int i=1;i<=n;i++)  cout<<i<<' ';
		cout<<endl;
	}
	return 0;
}

B

#include <bits/stdc++.h>
#define int long long
using namespace std;

int t,n,m;
char a[105][105];

signed main()
{
	cin>>t;
	while (t--)
	{
		cin>>n>>m;
		for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=m;j++)  cin>>a[i][j];
		}
		int ans=0;
		for (int i=1;i<=n-1;i++)
		{
			if (a[i][m]!='D')  ans++;
		}
		for (int i=1;i<=m-1;i++)
		{
			if (a[n][i]!='R')  ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
}

C

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7; 

int n;

int quick_power(int a,int b)
{
	int res=1;
	for (;b;b=b>>1,a=(a*a)%mod)
	{
		if (b&1)  res=(res*a)%mod;
	}
	return res;
}

signed main()
{
	cin>>n;
	int tot=1;
	for (int i=1;i<=n;i++)  tot=(tot*i)%mod;
	
	tot=((tot-quick_power(2,n-1))%mod+mod)%mod;
	cout<<tot<<endl;
	
	return 0;
}

D

#include <bits/stdc++.h>
#define int long long
#define inf 2000000007
using namespace std;

int n,m,x,ans=inf;
int dp[1000005][8];
char ch;

vector<int> a[1000005];
vector<int> b[1000005];

signed main()
{
	cin>>n>>m;
	if (n>=4&&m>=4)  return cout<<-1<<endl,0;
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=m;j++)  cin>>ch,a[i].push_back(ch-'0');
	}
	if (n<m)//2 4
	{
		for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=m;j++)  b[j].push_back(a[i][j-1]);
		}
		for (int i=1;i<=n;i++)  a[i].clear();
		swap(n,m);
		
		for (int i=1;i<=n;i++)
		{
			for (int j=0;j<m;j++)  a[i].push_back(b[i][j]);
		}
	}
	for (int i=1;i<=n;i++)
	{
		for (int j=0;j<8;j++)  dp[i][j]=inf;
	}
	if (m==1)  return cout<<0<<endl,0;
	else if (m==2)
	{
		for (int i=0;i<4;i++)
		{
			int x=i>>1,y=i&1;
			dp[1][i]=(a[1][0]!=x)+(a[1][1]!=y);
		}
		for (int i=2;i<=n;i++)
		{
			for (int j=0;j<4;j++)
			{
				int x=j>>1,y=j&1;
				for (int k=0;k<4;k++)
				{
					int X=k>>1,Y=k&1;
					if ((x+y+X+Y)%2)  dp[i][j]=min(dp[i][j],dp[i-1][k]);
				}
				dp[i][j]+=(a[i][0]!=x)+(a[i][1]!=y);
			}
		}
		for (int i=0;i<4;i++)  ans=min(ans,dp[n][i]); 
	}
	else if (m==3)
	{
		for (int i=0;i<8;i++)
		{
			int x=i>>2,y=(i>>1)&1,z=i&1;
			dp[1][i]=(x!=a[1][0])+(y!=a[1][1])+(z!=a[1][2]);
		}
		for (int i=2;i<=n;i++)
		{
			for (int j=0;j<8;j++)
			{
				int x=j>>2,y=(j>>1)&1,z=j&1;
				for (int k=0;k<8;k++)
				{
					int X=k>>2,Y=(k>>1)&1,Z=k&1;
					if ((x+y+X+Y)%2&&(y+z+Y+Z)%2)  dp[i][j]=min(dp[i][j],dp[i-1][k]);
				}
				dp[i][j]+=(a[i][0]!=x)+(a[i][1]!=y)+(a[i][2]!=z);
			}
		}
		for (int i=0;i<8;i++)  ans=min(ans,dp[n][i]); 
	}
	cout<<ans<<endl;
	
	return 0;
}

E

#include <bits/stdc++.h>
#define int long long
using namespace std;
 
int t,n,m,u,v,maxv=0,ans=0,cnt=0,pos;
int head[500005],visited[500005],depth[500005];
 
vector<int> a[500005];
 
struct edge
{
	int next;
	int to;
}e[2000005];
 
inline void add_edge(int u,int v)
{
	cnt++;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
 
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	
	while (ch<'0'||ch>'9')
	{
		if (ch=='-')  w=-w;
		ch=getchar();
	}
	while (ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+(ch^'0');
		ch=getchar();
	}
	return s*w;
}
 
inline void dfs(int now,int dep)
{
	a[dep].push_back(now);
	depth[now]=dep;
	visited[now]=1;
	
	if (depth[now]>maxv)
	{
		maxv=depth[now];
		pos=now;
	}
	for (int i=head[now];i;i=e[i].next)
	{
		if (!visited[e[i].to])  dfs(e[i].to,dep+1);
	}
}
 
inline void work(int now)
{
	if (depth[now]==1)
	{
		cout<<now<<' ';
		return;
	}
	for (int i=head[now];i;i=e[i].next)
	{
		if (depth[e[i].to]+1==depth[now])
		{
			work(e[i].to);
			break;
		}
	}
	cout<<now<<' ';
}
 
signed main()
{
	cin>>t;
	while (t--)
	{
		cin>>n>>m;
		maxv=0,cnt=0;
		for (int i=1;i<=n;i++)
		{
			head[i]=visited[i]=0;
			a[i].clear();
		}
		for (int i=1;i<=2*m;i++)  e[i].next=e[i].to=0;
		for (int i=1;i<=m;i++)
		{
			u=read(),v=read();
			add_edge(u,v);
			add_edge(v,u);
		}
		dfs(1,1);
		
		if (maxv>=(n+1)/2)
		{
			cout<<"PATH"<<endl;
			cout<<maxv<<endl;
			work(pos);
			cout<<endl;
			continue;
		}
		else
		{
			ans=0;
			for (int i=1;i<=n;i++)  ans+=a[i].size()/2;
			
			cout<<"PAIRING"<<endl;
			cout<<ans<<endl;
			for (int i=1;i<=n;i++)
			{
				if (a[i].size()<=1)  continue;
				for (int j=0;j<a[i].size()-1;j+=2)  cout<<a[i][j]<<' '<<a[i][j+1]<<endl;
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/107905396