[NOI Online #2 提高组] 涂色游戏
思路:
- 首先令 \(p_1<p_2\)
- 如果 \(gcd(p_1,p_2)!=1\) , 容易想到令 \(d=gcd(p_1,p_2),p_1=p_1/d,p_2=p_2/d\) 使得 \(gcd(p_1,p_2)==1\) , 即使 \(p_1,p_2\) 互质
- 至于为是么要使它们互质
- 第一减少区间范围
- 第二可以使\(p_1\)和\(p_2\)的倍数相邻
- 否则\(p_1\)和\(p_2\)的倍数必然最小相距\(d\)
- 考虑染蓝色的其中任意一个点 \(n*p_2\) 和接着的一个点 \((n+1)*p_2\)
- 即染红色的起点为 \(n*p_2+1\) 和终点为 \((n+1)*p_2-1\)
- 所以如果开始不让它们互质的话,可以将其表示为起点为 \(n*p_2+d\) 和终点为 \((n+1)*p_2-d\)
- 化简到最后为 \((p_2-2*d)/p_1+1>=k\)
- 这中间的间隔为 \(((n+1)*p_2-1)-(n*p_2+1)=p_2-2\)
- 那么最长连续染红色的个数为 \((p_2-2)/p_1+1\)
- 这里加 \(1\) 是考虑两种情况
- 如果 \((p_2-1)\)(原长度) 整除 \(p_1\) 加 \(1\) 就是把原来算掉的数加上来
- 如果 \((p_2-1)\) 不整除 \(p_1\) 那么\((p_2-1)/p1=(p_2-2)/p1\) 此时加 \(1\) 就是进 \(1\)
- 相当于处理进位
- 那么如果 \((p_2-2)/p_1+1>=k\) 输出 \(NO\) 否则输出 \(YES\)
- 注意
- 当 \(k==1\) 时 , 一定不可以,输出 \(NO\)
- 当 \(p_1<=p_2<=2\)&&\(k!=1\) 时 , 一定可以,输出 \(YES\)
code
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int gcd(int m,int n)
{
return n==0?m:gcd(n,m%n);
}
int main()
{
int T,p1,p2,k,d;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&p1,&p2,&k);
if(p1>p2) d=p1,p1=p2,p2=d;
d=gcd(p1,p2),p1=p1/d,p2=p2/d;
if(((p2-2)/p1+1>=k&&p2>2)||(k==1)) puts("NO");
else puts("YES");
}
return 0;
}