codeforces edu 139 (经典教育场被教育)

题目

C
题意: 给定2*n的矩阵,保证每一列至少有一个1。选择一条路径,通过所有的1有且仅有一次。
思路: 可以从第一列的1出发,因为至少有一个1.如果同一列的另一个位置是1,必走到那里,否则向右走再走回到那个1必定存在某个点走两次了。然后根据这个可以判断出是否存在合法方案。只要第一列的两个元素有一个合法即可。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int n = 2,m,k,T;
char b[3][N];
int a[3][N];
bool check(int wh)
{
	for(int i=1;i<=m;++i)
	{
		if(a[wh][i]==0) return 0;
		if(a[3-wh][i]==1) wh = 3-wh;
	}
	return 1;
}
void solve()
{
	cin>>m;
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=m;++j)
		{
			cin>>b[i][j];
			if(b[i][j]=='B') a[i][j] = 1;
			else a[i][j] = 0;
		}
	}
	if(check(1)||check(2)) cout<<"YES";
	else cout<<"NO";
	cout<<"\n";
}
signed main(void)
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); 
	cin>>T;
	while(T--)
	solve();
	return 0;	
} 

D
题意: 给定x,y,最大的k,满足gcd(x,y) = gcd(x+1,y+1) = gcd(x+k-1,y+k-1) = 1,gcd(x+k,y+k) != 1.
思路:
gcd具有的一个性质,与差分数组的gcd相同.
gcd(a1,a2,a3) = gcd(a1,a2-a1,a3-a2).
所以gcd(x+k,y+k) = gcd(x+k,y+k-(x+k)) = gcd(x+k,y-x).
说明x+k含有y-x的质因子。
然后可以质因数分解掉y-x,因为y-x是固定的,得到y-x的质因子p。
之后看k应该取多少,x+k是p的倍数。
(p-x%p)%p
x%p是x比p的倍数多多少,p-x%p是需要补多少,但是如果恰好是p的倍数这个结果就是p了,实际是0,所以要%p.
代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e7+10;
int n,m,k,T;
bool vis[N]; //�Ƿ����� 
int minp[N]; //����������
vector<int> prime; 
int gcd(int a,int b)
{
	if(b==0) return a;
	return gcd(b,a%b);
}
void init(int n)
{
	for(int i=1;i<=n;++i) minp[i] = i;
	memset(vis,1,sizeof(vis));
	for(int i=2;i<=n;++i)
	{
		if(vis[i]) prime.push_back(i);
		for(int j=0;j<prime.size()&&i*prime[j]<=n;++j)
		{
			vis[i*prime[j]] = 0;
			minp[i*prime[j]] = prime[j];
			if(i%prime[j]==0) 
			{
				break;
			}
		}
	}
}
void solve()
{
	int x,y; cin>>x>>y;
	if(x+1==y)
	{
		cout<<-1<<"\n"; return ;
	}
	int d = y-x;
	int t = d;
	int ans = 1e9;
	while(t>1) //�ֽ������� 
	{
		int p = minp[t];
//		cout<<t<<":"<<p<<"??\n";
		ans = min(ans,(p-x%p)%p);
		t /= p;
	}
	cout<<ans<<"\n";
}
signed main(void)
{
	init(N-1);
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>T;
	while(T--)
	solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值