[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;
}
原文地址:https://www.cnblogs.com/vasairg/p/12812896.html