C. Round Corridor(模拟思维题)

C. Round Corridor(模拟思维题)_第1张图片
C. Round Corridor(模拟思维题)_第2张图片
题意,就是把内部均分为n份,外部均分为m份,根据题意编号,给每个的编号,判断坐标之间是不是能够到达;
我一看,就想到了
1.m==n的情况,这种情况就可以直接判断是不是在同一个对应区域就行了也就是:
C. Round Corridor(模拟思维题)_第3张图片
那么需要满足的条件就是:

if(m==n){
		  	   if((sx==1&&ex==2&&sy==ey)||(sx==2&&ex==1&&sy==ey)||(sx==1&&ex==1&&sy==ey)||(sx==2&&ex==2&&sy==ey))puts("YES");
		  	   else puts("NO");
		  }

之后仔细思考坐标之间能到达的条件是什么,可以发现与内部和外部分块的比例关系有关,比如题中的:
C. Round Corridor(模拟思维题)_第4张图片
这里n:m2:3那么也就是说内部2个块对应外部3个块就会出现一个墙,就把它们分开,所以对应的部分不能到达其他被墙隔开的部分;
也就是(这里用红色表示内部分块边界,蓝色表示外部分块边界):
C. Round Corridor(模拟思维题)_第5张图片
然后可以发现:n/2,m/3(n/2
m/3,因为成比例)不就是对齐边界的个数吗?所以这里可以用除法来判断sy,ey是不是在同一个边界块内部,就可以判断是不是能够到达了(注意这里边界需要-1在除以相应的n/2和m/3);
好了!这道题答案就出来了(不愧是思维题,看起来没思路,结果想一想就出来了):

#include
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){
	return b?gcd(b,a%b):a;
}
int main(){
	ll n,m,q,sx,sy,ex,ey;;
	scanf("%lld %lld %lld",&n,&m,&q);
	while(q--){
		  scanf("%lld %lld %lld %lld",&sx,&sy,&ex,&ey);
		  if(m==n){//这种是相等的情况
		  	   if((sx==1&&ex==2&&sy==ey)||(sx==2&&ex==1&&sy==ey)||(sx==1&&ex==1&&sy==ey)||(sx==2&&ex==2&&sy==ey))puts("YES");
		  	   else puts("NO");
		  }else {
		  	  ll n1=n/gcd(n,m);//求  边界对齐的 一个有多少大块
		  	  ll m1=m/gcd(n,m);
		  	  if(sx==1&&ex==2){//在内部和外部
		  	  	    ll k1=(sy-1)/n1;//注意需要减1//可以用笔算一下就好理解了;(因为在边界的时候需要注意 除法丢弃小数部分)
		  	  	    ll k2=(ey-1)/m1;
		  	  	    if(k1==k2)puts("YES");
		  	  	    else puts("NO");
				}else if(sx==2&&ex==1){//在外部和内部
					ll k1=(sy-1)/m1;
					ll k2=(ey-1)/n1;
					if(k1==k2)puts("YES");
					else puts("NO");
				}else if(sx==1&&ex==1){//都在内部
					  int k1=(sy-1)/n1;
					  int k2=(ey-1)/n1;
					  if(k1==k2)puts("YES");
					  else puts("NO");
				}else if(sx==2&&ex==2){///都在外部
					  int k1=(sy-1)/m1;
					  int k2=(ey-1)/m1;
					  if(k1==k2)puts("YES");
					  else puts("NO");
				}
		  }
	}
   return 0;
}

你可能感兴趣的:(数学几何,模拟题(逻辑思维))