[NOI Online #2 提高组] 涂色游戏

[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;
}
posted @ 2020-05-01 11:14  白菜道士  阅读(183)  评论(2编辑  收藏  举报