题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5050
题面:
3 10 100 100 110 10010 1100
Case #1: 10 Case #2: 10 Case #3: 110
求两个以二进制形式给出的数的最大公约数的二进制表示。
解题:
这是有一条公式的,不知道可能就没法做。
1.a,b都为偶数。gcd(a,b)=2*gcd(a/2,b/2)。
2.a为偶数,b为奇数。gcd(a,b)=gcd(a/2,b)。
3.a,b都为奇数(设a大于等于b)。gcd(a,b)=gcd((a-b),b)。
然后用字符串模拟即可。(代码比较挫,还是自己写吧,囧)
代码:
#include <iostream> #include <string> #include <algorithm> using namespace std; string ans; int cnt; //比较大小 bool compare(string x,string y) { return x>y;} //取小 string min(string x,string y) { if(x.length()<y.length()) return x; else if(x.length()>y.length()) return y; else { if(compare(x,y)) return y; else return x; } } //取大 string max(string x,string y) { if(x.length()>y.length()) return x; else if(x.length()<y.length()) return y; else { if(compare(x,y)) return x; else return y; } } //相减 string subtract(string x,string y) { string res=""; reverse(x.begin(),x.end()); reverse(y.begin(),y.end()); y+=string(x.length()-y.length(),'0'); int len=x.length(),bor=0,tmp; for(int i=0;i<len;i++) { tmp=x[i]-y[i]+bor; if(tmp==0) { res+='0'; bor=0; } else if(tmp==1) { res+='1'; bor=0; } else if(tmp==-1) { res+='1'; bor=-1; } else { res+='0'; bor=-1; } } reverse(res.begin(),res.end()); bool sign=true; len=res.length(); int p=-1; for(int i=0;i<len;i++) { if(res[i]=='0') p=i; else break; } //去前导0 res=res.substr(p+1); return res; } //求公约数 void gcd(string x,string y) { string minn,maxn; //y已经为0了 if(y=="") { ans=x; return; } char s,t; s=x[x.length()-1]; t=y[y.length()-1]; //同偶 if(s=='0'&&t=='0') { cnt++; gcd(x.substr(0,x.length()-1),y.substr(0,y.length()-1)); } //同奇 else if(s=='1'&&t=='1') { minn=min(x,y); maxn=max(x,y); gcd(minn,subtract(maxn,minn)); } //一奇一偶 else if(s=='0'&&t=='1') { gcd(x.substr(0,x.length()-1),y); } else gcd(x,y.substr(0,y.length()-1)); } int main() { int t; cin>>t; string a,b; for(int i=1;i<=t;i++) { cnt=0; cin>>a>>b; gcd(a,b); //补约掉的2 for(int j=0;j<cnt;j++) ans+='0'; cout<<"Case #"<<i<<": "; cout<<ans<<endl; } return 0; }