http://acm.hdu.edu.cn/showproblem.php?pid=4937
给定一个数n,若这个数在base进制下全由3,4,5,6组成的话,则称base为n的幸运进制,给定n,求有多少个幸运进制。无穷多个的话输出-1,单个位置上超过9用相应的字符表示。
特判n为3~6才会无穷多解
暴力+二分
先特别求出只有两位和用二分求出只有三位表示的对应base数,然后从base = 4开始暴力遍历即可
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <queue> #include <vector> #include<set> #include <iostream> #include <algorithm> using namespace std; #define RD(x) scanf("%d",&x) #define RD2(x,y) scanf("%d:%d",&x,&y) #define clr0(x) memset(x,0,sizeof(x)) typedef long long LL; int main() { int _;RD(_);LL n; for(int tt = 1;tt <= _;++tt){ int i,j,k; scanf("%I64d",&n); LL t = n; bool flag = 1; if(t>=3&&t<=6){ printf("Case #%d: -1\n",tt); continue; } if (n <= 10){ printf("Case #%d: 0\n",tt); continue; } LL ans = 0; for(i=3;i<=6;++i){ t = n-i; for(j=3;j<=6;++j) if(t % j == 0 && t/j > i && t/j > j) ++ans; } for (i=3;i<=6;++i) for (j=3;j<=6;++j) for (k=3;k<=6;++k){ LL l = 0 , r = (LL)sqrt(n)+1 , mid; while (l < r){ mid = (l+r)>>1; t = i + mid*mid*k + mid*j; if (t >= n) r = mid; else l = mid+1; } t = i + l*l*k + l*j; if (t == n && i < l && j < l && k < l) ++ans; } for (j=4;j;++j){ t = n; bool flag = 1; k = 0; while (t){ int tmp = t % j; k++; if(tmp <3 || tmp > 6){ flag = 0; } t /= j; } if(k < 4)break; if (flag) ++ans; } printf("Case #%d: %I64d\n",tt,ans); } return 0; }