アットウィキロゴ

全体公開 > 合同練習会 > 20130323 > K 等式

問題の概要

x, y, zを変数として持ち, 演算は+と*のみであるようなものが左辺に現れ, 右辺は100以下の正整数であるような式が与えられる.
これを満足する正整数x, y, zの組み合わせの総数を答えよ.

実装の方針, 注意点

+ ...
x, y, zをそれぞれ1から100まで変化させ, 全パターン調べる.
但し, 式に出てこない変数は固定する.

100^3回もstringからパースすると重いので, 各項について, 係数と, 変数のべきを先に調べておく.

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx+1=1 に対する答えが 0 である事に注意せよ.
intで計算していると, オーバーフローし, xが2の倍数の時, 等号が成立してしまう.
大きくなってきたらダメと判定するか, double等で判定する必要がある.

ソースコード

Not verified
+ ...
  1. bool inRange(int a, int x, int b){
  2. return a <= x && x < b;
  3. }
  4. bool solve(){
  5. string s;
  6. getline(cin, s);
  7. if(s[0] == '.') return false;
  8.  
  9. vvi term(3, vi(1)); // 各変数の i 項目のべき
  10. vi c(1); // i 項目の係数
  11. int use[3] = {};
  12. int n = 0;
  13. int ans = 0;
  14. for(int p = 0; ; ++p){
  15. if(s[p] == '+' || s[p] == '='){
  16. if(!c[n]) c[n] = 1;
  17. ++n;
  18. if(s[p] == '+'){
  19. rep(i, 3) term[i].pb(0);
  20. c.pb(0);
  21. }else{
  22. ++p;
  23. while(p < sz(s)){
  24. ans *= 10;
  25. ans += s[p] - '0';
  26. ++p;
  27. }
  28. break;
  29. }
  30. }else if(s[p] == '='){
  31. }else if(inRange('0', s[p], '9'+1)){
  32. c[n] *= 10;
  33. c[n] += s[p]-'0';
  34. }else{
  35. ++term[s[p]-'x'][n];
  36. use[s[p]-'x'] = true;
  37. }
  38. }
  39.  
  40. int res = 0;
  41. int xyz[3];
  42. for(xyz[0] = 1; xyz[0] <= (use[0] ? 100 : 1); ++xyz[0]){
  43. for(xyz[1] = 1; xyz[1] <= (use[1] ? 100 : 1); ++xyz[1]){
  44. for(xyz[2] = 1; xyz[2] <= (use[2] ? 100 : 1); ++xyz[2]){
  45. double s = 0;
  46. rep(i, n){
  47. double t = c[i];
  48. rep(j, 3) rep(k, term[j][i]) t *= xyz[j];
  49. s += t;
  50. }
  51. if(abs(s - ans) < 0.5) ++res;
  52. }
  53. }
  54. }
  55. cout << res << endl;
  56.  
  57. return true;
  58. }
  59.  



最終更新:2013年03月28日 15:14