您的位置:首页 > 其它

ural 1803

2014-08-10 00:13 295 查看
求Fibonacci的第n项K进制表示后各个位的和。

采用压缩的方式,表示成k ^ n进制,k ^ n < 1000000的,可以先预处理出来k ^ n各个数的位数之和。

然后直接采用模拟加法的方法进行计算。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 3000;

long long f[maxn];

struct Ans {
int cnt_num;
int order;
bool operator < (const struct Ans &a) const {
if (cnt_num == a.cnt_num) {
return order < a.order;
}
return cnt_num < a.cnt_num;
}
};

int sum[1000007];
struct Bign {
int num[maxn];
int num_len;
int getAns() {
int ret = 0;
for (int i = 0; i < num_len; i++) {
ret += sum[num[i]];
}
return ret;
}
Bign() {
num_len = 0;
memset(num, 0, sizeof(num));
}
};
int n, k;
struct Bign a, b, c;
struct Ans ans[50007];
int mod;
int main() {
//    freopen("in.txt", "r", stdin);
scanf("%d%d", &k, &n);
mod = k;
while (mod * k <= 1000000) {
mod = mod * k;
}
for (int i = 0; i <= mod; i++) {
int x = i;
int temp = 0;
while (x) {
temp += x % k;
x /= k;
}
sum[i] = temp;
}
a.num[0] = 1;
a.num_len = 1;
b.num[0] = 1;
b.num_len = 1;
ans[1].cnt_num = 1;
ans[1].order = 1;
ans[2].cnt_num = 1;
ans[2].order = 2;
for (int i = 3; i <= n; i++) {
int pre = 0;
int j;
for (j = 0; j < a.num_len || j < b.num_len || pre; j++) {
int next = (a.num[j] + b.num[j] + pre) % mod;
c.num[j] = next;
pre = (a.num[j] + b.num[j] + pre) / mod;
}
c.num_len = j;
ans[i].order = i;
ans[i].cnt_num = c.getAns();
a = b;
b = c;
}
sort(ans + 1, ans + 1 + n);
for (int i = 1; i <= n; i++) {
printf("%d ", ans[i].order);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: