题意:
无限篱笆,给你r,b,k,篱笆编号是r的倍数的turn red,b的倍数的turn blue,既是r倍数又是b倍数可以任意颜色,其余不染色。现将所有painted篱笆编号取出升序排列,问你是是否任意连续k个颜色都可以做到different,做不到输出REBEL,否则OBEY
题外话:比赛的时候一开始搞错题意了,后来更正了大脑却一直在放空没有思考进去,最近心情不好有点低迷做题也懵懵的想不进去本来可做的也失了智还是应该反思一下这是怎么了T_T,多亏夏总带躺才没有掉分%%%%
思路
假设Max是连续相同颜色篱笆的最大值 即k > Max is OK
那么当我们swap保证b大后 存在:
1.b % r == 0,则Max = (b / r) - 1 ;
2.b % r == 1,那么Max最少最少也要是b / r,此时考虑会不会存在Max+1的情况,我们考虑对于每一个以b为长度的区间中最多能存在几个red,即相连red的最大值,朝着最多安插这个极端去向,在一个length = b的区间中,最左边的red距离左边界距离最短是gcd(r,b)[建议画图,清晰明了]。现在对于这个区间剩下的长度,即b - gcd(b,r)考虑还能放几个red:(b - gcd(b,r)) / r。社上面的答案为cur,这里要特别判断一下是否整除,整除的话最后一个篱笆我们为了使Max最小必然涂成blue,所以cur--。好的到这里只需要看cur ?= Max,最前面那个red是否挤进去了来决定Max是否++就好了。
Accode
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf = 0x3f3f3f3f;
int t,r,b,k,Max;
int gcd(int a,int b){
if(!b) return a;
return gcd(b,a % b);
}
int main()
{
scanf("%d", &t);
while(t--){
scanf("%d %d %d", &r, &b, &k);
if(b < r) swap(r, b);
if(!(b % r)) Max = b / r - 1;//整除关系
else{
Max = b / r;//at least
int fuck = gcd(b,r);
int cur = (b - fuck) / r;
if(!((b - fuck) % r)) cur--;
if(cur == Max) Max++;
}
//Max是最大连续相同篱笆
if(k > Max) printf("OBEY\n");
else printf("REBEL\n");
}
}