Codeforces Round #639 (Div. 2)

这场比赛打的真糟心,幸亏不计分了,美滋滋的溜了。。。
A 只有一行或者只有一列是一定可以的,其他情况只有两行两列可以(首尾相连排一圈)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200010;
int t,n,m;
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		if(n==1||m==1||(n==2&&m==2)) puts("YES");
		else puts("NO"); 
	}
	return 0;
}

B 可以推出来高度n的塔需要木棍的数量,然后二分就可以了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=30010;//暴力一遍 好像27000就超过1e9了
int t,n,m;
ll sum[N];
int main()
{
	sum[1]=2;
	for(int i=2;i<N;i++)
		sum[i]=sum[i-1]+1ll*3*i-1;
	cin>>t;
	while(t--)
	{
		cin>>n;
		int cnt=0;
		while(n>1)
		{
			int l=upper_bound(sum+1,sum+N,n)-sum;
			cnt++;
			n-=sum[l-1];
		}
		cout<<cnt<<endl;
	}
	return 0;
}

C 题意好恶心人。。。
一个酒店有无数个房间,编号是任意整数(可以是正负或0)。
已知现在每个房间都一个人,要重新排序,排序规则是:给你一个长度为n的数组,然后让编号为k房间内的人去编号为 k+a[ k mod n](k可以是正或负或0) 的房间,问排序后是否还是一人一个房间。
如果不满足那个一定存在两个数k1,k2 使得k1+a[k1 mod n]==k2+a[k2 mod n]成立 。
假如 k1,和k2都属于[0,n),那么上式就是:k1+a[k1] = = k2+a[k2]。
假如k1属于[0,n),k2不属于[0,n),那么上式就是:k1+a[k1] = = k2+a[k2 mod n]
令k2=m2
n+s2,则可化简为 k1+a[k1] = = m2
n+s2+a[s2]。
k1和k2相反情况是一样的。
假如k1和k2都不属于[0,n),那么上式就是:k1+a[k1 mod n] = = k2+a[k2 mod n];
再令k1=m1n+s1则化简为:m1n+s1+a[s1] = = m2*n+s2+a[s2];
移项后得 s1+a[s1]==(m2-m1)*n+s2+a[s2]。
综上可得:s1+a[s1] ≡ s2+a[s2](mod n) (s1,s2属于[0,n) )

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200010;
int t,n,m;
int a[N];
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(int i=0;i<n;i++) cin>>a[i];
		map<ll,int> mp1,mp2;
		bool flag=1;
		for(int i=0;i<n;i++)
		{
			int x=((a[i]+i)%n+n)%n;
			if(mp1[x]) 
			{
				flag=0;
				break;
			}
			mp1[x]=1;
		}
		if(flag) puts("YES");
		else puts("NO");
	}
	return 0;
}

D 看样例可以发现如果某一行或者某一列有1个以上的连续黑段,那么一定是-1;
如果存在某行全都是白色,那么是否可以将整体分为两部分来分治处理,这两部分应该是可行的,但是南磁极必须分布于每一行,这个全白行必须有一个南磁极,那就必须会有北磁极被吸引过来位于白块之上就不满足题意了,但是也有例外如果同时存在全白列呢,将南磁极放于行列交点,那么它的同行同列一定不会有北磁极,就一定不会有北磁极被吸到白块之上。
所以如果只有全白行或者全白列就是-1(观摩榜一代码得来的,分治是我臆想的(一本正经胡说八道)).
其余情况就是找北磁极的数量了,求连通块的数量即可。

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;
char s[N][N];
bool st[N][N];
int d[4][2]={0,1,0,-1,1,0,-1,0};
void dfs(int x,int y)
{
	st[x][y]=1;
	for(int i=0;i<4;i++)
	{
		int dx=x+d[i][0],dy=d[i][1]+y;
		if(s[dx][dy]=='#'&&!st[dx][dy])
			dfs(dx,dy);
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>s[i]+1;
	bool flag1=1,flag2=1;//标记是否有全白行和全白列
	for(int i=1;i<=n;i++)
	{
		int cnt=0;//记录变化次数
		if(s[i][1]=='#') cnt++;//假设s[i][0]是'.'
		for(int j=2;j<=m;j++) 
			if(s[i][j]!=s[i][j-1]) cnt++;
		if(cnt>2) 
		{
			puts("-1");
			return 0; 
		}
		if(!cnt) flag1=0;
	}
	for(int i=1;i<=m;i++)
	{
		int cnt=0;
		if(s[1][i]=='#') cnt++;
		for(int j=2;j<=n;j++) 
			if(s[j][i]!=s[j-1][i]) cnt++;
		if(cnt>2) 
		{
			puts("-1");
			return 0;
		}
		if(!cnt) flag2=0;
	}
	if(flag1!=flag2)
		puts("-1");
	else
	{
		int ans=0;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
				if(s[i][j]=='#'&&!st[i][j])
				{
					dfs(i,j);
					ans++;
				}
		cout<<ans;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/neflibata/p/12871737.html