题目大意:将两个二进制数的GCD用二进制数表示出来。
题目分析:这道题可以用java中的大数类AC。
代码如下:
import java.io*; import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String agrs[]){ Scanner sc=new Scanner(System.in); int T=sc.nextInt(); for(int i=1;i<=T;++i){ String p=sc.next(); String q=sc.next(); BigInteger a=new BigInteger(p,2); BigInteger b=new BigInteger(q,2); a=a.gcd(b); System.out.print("Case #"+i+": "); System.out.println(a.toString(2)); } sc.close(); } }
不过,也可以用二进制来求GCD。
gcd(a,b)=gcd(a/2,b/2)*2 (a,b均为偶数)
gcd(a,b)=gcd(a,b/2) (a为奇数,b为偶数)
gcd(a,b)=gcd((a-b)/2,b) (a,b均为奇数)
很可惜我用C++没AC,下面是我没AC的代码:
# include<iostream> # include<cstdio> # include<cstring> # include<algorithm> # include<string> using namespace std; bool isBigger(string p,string q) { if(p.length()>q.length()) return true; else if(p.length()<q.length()) return false; else{ int len=p.length(); for(int i=len-1;i>=0;--i){ if(p[i]>q[i]) return true; else if(p[i]<q[i]) return false; } } } string sub(string p,string q) { int len=q.length(); for(int i=0;i<len;++i){ if(p[i]>=q[i]) p[i]=p[i]-q[i]+'0'; else{ p[i+1]-=1; p[i]=p[i]+2-q[i]+'0'; } } for(int i=len;i<p.length();++i){ if(p[i]<'0'&&i+1<p.length()){ --p[i+1]; p[i]+=2; } } len=p.length(); while(p[len-1]<='0'&&len>0) --len; return p.substr(0,len); } string f(string p,string q) { if(p==q) return p; if(p=="1") return "1"; if(q=="1") return "1"; int n=p.length(),m=q.length(); if(p[0]=='0'&&q[0]=='0') return f(p.substr(1,n-1),q.substr(1,m-1))+'0'; else if(p[0]=='1'&&q[0]=='0') return f(p,q.substr(1,m-1)); else if(p[0]=='0'&&q[0]=='1') return f(p.substr(1,n-1),q); else{ if(isBigger(p,q)){ p=sub(p,q); n=p.length(); return f(p.substr(1,n-1),q); }else{ q=sub(q,p); m=q.length(); return f(p,q.substr(1,m-1)); } } } int main() { int T; string p,q; scanf("%d",&T); for(int i=1;i<=T;++i){ cin>>p>>q; reverse(p.begin(),p.end()); reverse(q.begin(),q.end()); cout<<"Case #"<<i<<": "<<f(p,q)<<endl; } return 0; }