HDU 4497 GCD and LCM 組合數學
阿新 • • 發佈:2018-12-11
題目思路:首先看題目,用測試資料想到了可以把最大公因數和最小公倍數分解質因數,然後對於每個質因數,例如2,最大公因數有2^1,最小公倍數有2^3,那麼x,y,z分解質因數中要有一個x或y或z有2^1,有一個有2^3,還有一個隨便取一個1~3之間的數,然後A(3,3),然後慢慢對所有質因數進行操作
AC程式碼
#include <iostream> #include<bits/stdc++.h> using namespace std; template <typename T> inline bool scan_d (T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; //EOF while (c != '-' && (c < '0' || c > '9') ) { if((c = getchar()) == EOF) return 0; } sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template<typename T> void print(T x) { static char s[33], *s1; s1 = s; if (!x) *s1++ = '0'; if (x < 0) putchar('-'), x = -x; while(x) *s1++ = (x % 10 + '0'), x /= 10; while(s1-- != s) putchar(*s1); } template<typename T> void println(T x) { print(x); putchar('\n'); } set<int>ans; int main() { int g,l; int t; scan_d(t); while(t--) { ans.clear(); map<int,int>cnt1; map<int,int>cnt2; scan_d(g); scan_d(l); for(int i=2;i*i<=g;++i) { while(g%i==0) { cnt1[i]++; g/=i; } } if(g>1) cnt1[g]++; for(int i=2;i*i<=l;++i) { while(l%i==0) { cnt2[i]++; l/=i; } } if(l>1) cnt2[l]++; for(auto pi:cnt1) ans.insert(pi.first); for(auto pi:cnt2) ans.insert(pi.first); long long result=1; for(auto pi:ans) { if(cnt2[pi]==cnt1[pi]) continue; if(cnt2[pi]<cnt1[pi]) { result=0; break; } if(cnt2[pi]>cnt1[pi]) result*=(cnt2[pi]-cnt1[pi])*6;//化簡前是(cnt2[pi]-cnt1[pi]-1)*6三個數全不同然後全排列+3(最後一個數與最小公因數的次數相同A(3,3)/2!)+3(最後一個數與最大公因數次數相同A(3,3)/2!) } println(result); } return 0; }