好久没打CF了,昨天重判前排名39,重判后错两个题排名890,真是给跪了。
题意:
隔壁老王有n个男朋友和m个女朋友,老王希望他们都开心,于是开始了他的脑残计划:第i天请编号为i%n的男朋友和编号为i%m的女朋友吃饭,这一天一起吃饭两个人如果有一个人开心,那么两个人都会永远开心。请问老王是否能让他的所有朋友都永远开心。
The first line contains two integer n and m (1 ≤ n, m ≤ 100).
The second line contains integer b (0 ≤ b ≤ n), denoting the number of happy boys among friends of Drazil, and then follow b distinct integers x1, x2, ..., xb (0 ≤ xi < n), denoting the list of indices of happy boys.
The third line conatins integer g (0 ≤ g ≤ m), denoting the number of happy girls among friends of Drazil, and then follow g distinct integers y1, y2, ... , yg (0 ≤ yj < m), denoting the list of indices of happy girls.
It is guaranteed that there is at least one person that is unhappy among his friends.
If Drazil can make all his friends become happy by this plan, print "Yes". Otherwise, print "No".
比赛的时候以为最多要lcm(n,m)天就可以遍历所有情况,结果pretest过了,rejudge跪了卧槽。仔细想了一下,m*n可以遍历所有组合情况,但是不一定m*n次就可以传达到(我TM也不知道这是什么意思),估计最多情况是(m+n)*mn,也就10^6,但是后来交代吗2*mn就过了,不知道是确实只需要这么多还是没有数据。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define mxn 110
int n,m,b,g;
bool flag[2][mxn];
int gcd(int x,int y){
return !y ? x : gcd(y,x%y);
}
int lcm(int x,int y){
return x/gcd(x,y)*y;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
scanf("%d",&b);
memset(flag,false,sizeof(flag));
for(int i=0;i<b;++i){
int tem;
scanf("%d",&tem);
flag[0][tem]=true;
}
scanf("%d",&g);
for(int i=0;i<g;++i){
int tem;
scanf("%d",&tem);
flag[1][tem]=true;
}
int day=m*n;
for(int i=0;i<=2*day;++i) if(flag[0][i%n]||flag[1][i%m])
flag[0][i%n]=flag[1][i%m]=true;
bool ans=true;
for(int i=0;i<n;++i) if(!flag[0][i])
ans=false;
if(ans) for(int i=0;i<m;++i) if(!flag[1][i])
ans=false;
if(ans) puts("Yes");
else puts("No");
}
return 0;
}