Codeforces 180 B. Divisibility Rules
問題
ある数が2で割り切れるかは、下一桁が2で割れるかを見ればよい。このような判別の仕方を2-typeという。
ある数が3で割り切れるかは各桁の和が3で割れるかを見ればよい。このような判別の仕方を3-typeという。
ある数が6で割り切れるかは、2-typeと3-typeの両方のチェックが必要である。このように、判別の仕方を複数組み合わせる判別の仕方を6-typeという。
ある数が11で割り切れるかは、偶数桁の和と奇数桁の和の差が11で割り切れるかを見ればよい。このような判別の仕方を11-typeという。
ある数が7で割り切れるかは、わからない。わからないものを7-typeという。
このように、b進数で数dで割り切れるかを知るには、どのタイプの判別を使えばよいかを答えよ。
複数の判別の仕方が使える場合、上で先に述べられたものを使うものとする。
2-typeの場合、下何桁を見ればよいかも出力せよ。
制約条件
2≦b, d≦100
方針
一生懸命場合わけして調べる。
3-typeと11-typeは、b % dの値を見れば判別できる。
そうでない場合、各素因数ごとにどのタイプで判別できるかを見る。
複数の判別が必要な場合は6-type.
b ^ n % di == 0なら2-type.
nが必要な桁数。
ソースコード
map<int, int> fac(int n){ map<int, int> res; for(int i = 2; i*i <= n; i++) if(n % i == 0){ int c = 0; while(n % i == 0) n /= i, c++; res[i] = c; } if(n > 1) res[n] = 1; return res; } void run(){ int d, b; cin >> b >> d; map<int, int> f = fac(d), g = fac(b); if(b % d == 1){ cout << "3-type" << endl; return; } if(b % d == d-1){ cout << "11-type" << endl; return; } int two = 0; bool three = 0, eleven = 0; fr(i, f){ if(!g.count(i->first)){ int p = 1; rep(j, i->second) p *= i->first; if(b % p == 1) three = 1; else if(b % p == p-1) eleven = 1; else{ cout << "7-type" << endl; return; } } else two = max(two, (g[i->first] + i->second - 1) / g[i->first]); } if((two != 0) + three + eleven > 1) cout << "6-type" << endl; else if(two){ cout << "2-type" << endl; cout << two << endl; } else if(three) cout << "3-type" << endl; else if(eleven) cout << "11-type" << endl; else assert(0); }