题意,就是把内部均分为n份,外部均分为m份,根据题意编号,给每个的编号,判断坐标之间是不是能够到达;
我一看,就想到了
1.m==n的情况,这种情况就可以直接判断是不是在同一个对应区域就行了也就是:
那么需要满足的条件就是:
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");
}
之后仔细思考坐标之间能到达的条件是什么,可以发现与内部和外部分块的比例关系有关,比如题中的:
这里n:m2:3那么也就是说内部2个块对应外部3个块就会出现一个墙,就把它们分开,所以对应的部分不能到达其他被墙隔开的部分;
也就是(这里用红色表示内部分块边界,蓝色表示外部分块边界):
然后可以发现:n/2,m/3(n/2m/3,因为成比例)不就是对齐边界的个数吗?所以这里可以用除法来判断sy,ey是不是在同一个边界块内部,就可以判断是不是能够到达了(注意这里边界需要-1在除以相应的n/2和m/3);
好了!这道题答案就出来了(不愧是思维题,看起来没思路,结果想一想就出来了):
#include<bits/stdc++.h>
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;
}