Codeforces Round #777 (Div. 2)

A. Madoka and Math Dad

题目链接:Problem - A - Codeforces

样例输入:

5
1
2
3
4
5

样例输出:

1
2
21
121
212

题意:给定一个n,构造一个十进制数,使得每一位的值都是正的而且相邻两位不能相同,各位数字之和为n,问这个十进制整数最大是多少?

分析:首先我们能够发现制约一个数的最重要因素是数的位数,其次才是最高位的值,为了使得我们构造的位数尽量多,我们应该用1和2来进行构造,也就是根据n对3取余的结果分类讨论一下即可。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int N=2e5+10;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		scanf("%d",&n);
		if(n%3==1)
		{
			printf("1");
			for(int i=1;i*3<=n;i++)
				printf("21");
		}
		else if(n%3==2)
		{
			printf("2");
			for(int i=1;i*3<=n;i++)
				printf("12");
		}
		else
		{
			for(int i=1;i*3<=n;i++)
				printf("21");
		}
		puts("");
	}
	return 0;
} 

B. Madoka and the Elegant Gift

题目链接:Problem - B - Codeforces

 样例输入:

5
3 3
100
011
011
3 3
110
111
110
1 5
01111
4 5
11111
01010
01000
01000
3 2
11
00
11

样例输出:

YES
NO
YES
NO
YES

题意:给定一个01矩阵,问是不是所有的全1矩阵都是不重叠的。

分析:通过简单分析可以发现,只要保证2*2的矩阵里面不是3个1即可

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int N=2e2+10;
char s[N][N];
int f[N][N];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		memset(f,0,sizeof f);
		for(int i=1;i<=n;i++)
		{
			scanf("%s",s[i]+1);
			for(int j=1;j<=m;j++)
			{
				if(s[i][j]=='1')
					f[i][j]=1;
				else
					f[i][j]=0;
				f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1];
			}
		}
		bool flag=true;
		for(int i=1;i+1<=n;i++)
		for(int j=1;j+1<=m;j++)
			if(f[i+1][j+1]-f[i-1][j+1]-f[i+1][j-1]+f[i-1][j-1]==3)
			{
				flag=false;
				break;
			}
		if(flag) puts("YES");
		else puts("NO");
	}
	return 0;
}

C. Madoka and Childish Pranks

题目链接:Problem - C - Codeforces

样例输入: 

4
4 5
01000
10100
01010
00110
2 3
001
010
3 3
110
101
000
1 1
0

样例输出:

4
1 1 3 3
3 3 4 4
4 3 4 4
4 2 4 3
1
1 2 2 3
-1
0

题意:给定一个01矩阵代表我们最终要构造的矩阵,一开始我们有一个初始矩阵为全0矩阵,然后我们每次可以选择一个子矩阵,对这个子矩阵操作后的结果就是左上角的位置变为0,距离左上角位置为奇数的位置变为1,距离为偶数的位置变为0.问能否通过有限次操作使得矩阵变为我们要构造的矩阵。

分析:这里可以选择采用1*2和2*1的矩阵进行构造,对于每一行,我们从后往前考虑,如果当前位置为1,那么我们就选择当前位置和当前位置左面一个位置进行一次操作,最后我们可以把除了第一列之外的矩阵全部操作完成,然后我们从第n行往上操作第1列矩阵,如果当前位置为1,那么我们就选择当前位置和上面一个位置进行一次操作,可以发现,只有当第一行第一列的空格是1时不合法,其他矩阵都是可以按照这种方法构造的。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int N=2e2+10,M=1e4+10;
char s[N][N];
int x1[M],y1[M],x2[M],y2[M];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		int tt=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%s",s[i]+1);
			for(int j=m;j>=2;j--)
			if(s[i][j]=='1')
				x1[++tt]=i,y1[tt]=j-1,x2[tt]=i,y2[tt]=j;
		}
		if(s[1][1]=='1') puts("-1"); 
		else
		{
			for(int i=n;i>1;i--)
			if(s[i][1]=='1')
				x1[++tt]=i-1,y1[tt]=1,x2[tt]=i,y2[tt]=1;
			printf("%d\n",tt);
			for(int i=1;i<=tt;i++)
				printf("%d %d %d %d\n",x1[i],y1[i],x2[i],y2[i]);
		}
	}
	return 0;
}

D. Madoka and the Best School in Russia

题目链接:Problem - D - Codeforces

样例输入: 

8
6 2
12 2
36 2
8 2
1000 10
2376 6
128 4
16384 4

样例输出:

NO
NO
YES
NO
YES
YES
NO
YES

题意:给定一个n,定义一个数x为good当且仅当n是d的倍数,定义一个数是beautiful当且仅当这个数是一个good数且不能表示成两个good数的乘积。现在给你一个x,问你能不能将这个数表示成若干个beautiful的乘积,如果能找出两种及以上的表示形式就输出YES,否则输出NO

分析:我们先来看一下beautiful数具备什么特征,首先其是一个good数就说明其含有一个因子d,但是由于其不能表示成两个gooc数的乘积,所以这个数里面至多含有一个因子d,不可能含有因子d*d,因为一旦含有d*d,那么一定可以被表示为两个good数的乘积。那么我们的目的就转变为将x表示成若干个数的乘积,其中每个数都只能含有一个因子d,其他因子无所谓,那么我们就可以按照下面的方法进行分类讨论:

我们先让x一直除以d,用cnt记录x含有d因子的幂次,最后x中就不再含有因子d,这个时候我们先来看一下cnt的情况,如果cnt<2,那么显然不能分成多个beautiful数的乘积直接输出NO,那么剩下的情况都是cnt>=2的情况,如果x是一个合数,不妨设x=a*b,那么我们显然就至少有两种划分方式:

x*d  d  ……,或者a*d  b*d  ……。那么对于x是合数的情况我们直接输出YES即可

下面就是x是质数的情况:

这个时候一种表示形式就是

x*d  d  ……。

接下来我们还需要找到另一种表示形式

因为x是一个质数,所以x肯定是已经没办法进行分解了,这个时候我们应该分解d

第一种情况:d是一个质数,那么d也无法分解,我们直接输出NO即可

第二种情况:d不止含有一个质因子,以k个质因子为例,假设是d=(p1^a1)*(p2^a2)*……*(pk^ak)

这个时候我们找一个质因子pi使得满足x*pi^ai不含有因子d,那么我们就可以把x*d分解为x*pi^ai和(p1^a1)*(p2^a2)*……(pi-1^ai-1)*(pi+1^ai+1)*……*(pk^ak),我们把这两个数分别作为两个d的系数即可,这样我们就找到了另外一种构造方式

最后一种情况就是d只含有一个质因子,不妨假设d=u^k,这个时候我们要将d分为(u^p)*(u^q),p+q=k,这个时候我们将两者其中一个和x相乘作为一个数(这个数不能含有因子d),另一个数作为第二个数即可构造出第二种形式,但是需要注意的一点是,当k等于2时,p和q都等于1,这个时候如果x等于u那么我们是没办法构造成功的,注意一下这种形式的特判即可。

细节见代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int N=2e5+10;
vector<int>p;
vector<int>t; 
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int x,d;
		scanf("%d%d",&x,&d);
		int cnt=0;//记录x中含有d的幂次 
		while(x%d==0)
		{
			x/=d;
			cnt++;
		}
		bool flag=true;
		for(int i=2;i*i<=x;i++)
			if(x%i==0)
			{
				flag=false;
				break;
			}
		if(cnt<2) puts("NO");
		else if(!flag) puts("YES");
		else//剩余因子x是一个质数 
		{
			p.clear();
			t.clear();
			int td=d;
			for(int i=2;i*i<=d;i++)
			{
				if(td%i==0)
				{
					p.push_back(i);
					int tt=0;
					while(td%i==0)
					{
						tt++;
						td/=i;
					}
					t.push_back(tt);
				}
			}
			if(td!=1) p.push_back(td),t.push_back(1);
			if(p.size()==1)//d只含有一个质因子 
			{
				if(t[0]==1)//d是一个质数
					puts("NO");
				else
				{
					if(cnt==2) puts("NO");
					else if(d==x*x&&cnt==3) puts("NO");
					else puts("YES");
				}
			}
			else
			{
				if(cnt==2) puts("NO");
					else puts("YES");
			}
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值