[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;
}