1001.没推到题解那么细,枚举一下也可以。用通分可以避免小数精度问题。
#include<iostream> #include<stdio.h> using namespace std; int main(){ int T; int n,m; int a,b,c; int i,j; bool flag; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); //对等式通分 a=m*(n-2); b=n*(m-2); c=n*m; flag=false; for(i=0;i<=6;++i){ for(j=0;j<=6;++j){ if(a*i+b*j==2*c){ flag=true; break; } } if(flag){ break; } } if(flag){ printf("Yes "); } else{ printf("No "); } } return 0; }
1002.判断某一位能取0和1的条件想了一会。
#include<iostream> #include<stdio.h> using namespace std; int myLen(long long n){ int sum=0; while(n>0){ ++sum; n>>=1; } return sum; } int main(){ long long pow[65]; int i; for(i=0;i<=62;++i){ pow[i]=(1LL)<<i; } int T; long long a,b,c,d; int max_len; long long sum1,sum2; bool f1,f2;//f1表示可以为0,f2表示可以为1 bool f3,f4;//f3表示可以为0,f4表示可以为1 long long ans; scanf("%d",&T); while(T--){ scanf("%lld%lld%lld%lld",&a,&b,&c,&d); if(b>d){ max_len=myLen(b); } else{ max_len=myLen(d); } sum1=sum2=0; ans=0; for(i=max_len-1;i>=0;--i){ f1=f2=false; f3=f4=false; //可以为0 if(sum1+pow[i]-1>=a){//这个条件好好想下。 f1=true; } if(sum2+pow[i]-1>=c){ f3=true; } //可以为1 if(sum1+pow[i]<=b){//这个条件好好想下。 f2=true; } if(sum2+pow[i]<=d){ f4=true; } if(f1&&f2&&f3&&f4){//2个数都可以为0和1 //剩余的可以全为1了,不用看了。 ans+=pow[i+1]-1; break;// } if(f1&&f4){//两个数可以分别为0,1 ans+=pow[i]; sum2+=pow[i]; } else if(f2&&f3){//两个数可以分别为1,0 ans+=pow[i]; sum1+=pow[i]; } else if(f2&&f4){//两个数都只能为1 sum1+=pow[i]; sum2+=pow[i]; } else{//两个数都只能为0 //无操作 } } printf("%lld ",ans); } return 0; }
1003.
1004.直接暴力莫比乌斯反演,超时了。抽空再看看。