题目链接:简单的等式
比赛的时候感觉没有思路,大腿说可能是枚举想一下有什么限制好了。然后莫名想出S(x, m)是有一个范围的,然后告知大腿,大腿敲之,WA之,发现maxn应该是10^18,num[i]的最大还是应该是10^9的。【据大腿说改成10^18就过了,然刚试了下,10^9即可。】
赛后重敲的时候,num数组想错了,比如说,10^10用m进制表示时,位数之和最大应该是9*9+1。然我算成10了。
还有个坑点在哪呢.....输入的时候n需要用long long表示 如果是%ll 就WA,如果是%I64d就AC,当然cin 大法也没有问题.....【遇见两次了,不解】
无脑的逐行排除才发现...以后再也不这样dbug了....T_T
附AC代码:
/*
思路:对于给定的m,S(x, m) 的范围可以确定最大值。
S(x, m) = n / x - x,函数递减,所以遍历x的时候,从sqrt(n) 遍历到S(X, m)递增到最大值过程中得到的满足条件的x的最小值即为ans.
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cmath>
#define maxn 1e9
using namespace std;
long long num[20];
void init() { // 计算maxn表示成进制时,各位之和相加的最大值
for (int i=2; i<=16; ++i) {
long long st = 1;
int ans = 0;
while(st <= maxn) {
st *= i;
ans += i-1;
}
num[i] = ans-i+1;
}
}
int get(long long x, int m) { // 计算x写成m进制各位相加之和
long long st = x;
int ans = 0;
while(st) {
ans += st % m;
st /= m;
}
return ans;
}
int main() {
init();
int t;
scanf("%d", &t);
while(t--) {
long long n;
int m;
scanf("%I64d%d", &n, &m);
long long st = (long long)sqrt(n);
long long ans = -1;
for (long long i=st; i>0; --i) {
if (n / i - i > num[m]) break;
if (n%i != 0) continue;
if (n / i - i == get(i, m)) {
ans = i;
}
}
printf("%lld\n", ans);
}
return 0;
}
对于这道题,从没有思路到想出S(x, m)限制,到代码实现都值得思考呢......
原文:http://www.cnblogs.com/icode-girl/p/5345931.html