题意:黄金比例进制,是用(1+sqrt(5))/2为进制的进制单位。在这样的进制下,正整数都能表示成有限的小数。给出如下的公式:
求给定的正整数黄金比例进制的表达。
思路:按照题目给出的两个方程,分别将两式都乘以φ^(n-2),得到: φ^(n-1)+φ^(n-2)=φ^n;2*φ^n=φ^(n+1)+φ^(n-2)。
这样,我们从十进制的表示,按照公式一步一步的模拟就可以啦。
代码如下:
<span style="font-size:12px;">#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 200;
int a[MAXN];
int n;
int main() {
while (scanf("%d", &n) != EOF) {
memset(a, 0, sizeof(a));
a[50] = n;
int flag = 1;
while (flag) {
flag = 0;
for (int i = 0; i < 100; i++)
if (a[i] && a[i+1]) {
int Min = min(a[i], a[i+1]);
a[i+2] += Min;
a[i] -= Min;
a[i+1] -= Min;
flag = 1;
}
for (int i = 2; i < 100; i++)
if (a[i] > 1) {
a[i-2] += a[i]/2;
a[i+1] += a[i]/2;
a[i] %= 2;
flag = 1;
}
}
int st,ed;
for (int i = 100; i >= 0; i--)
if (a[i]) {
st = i;
break;
}
for (int i = 0; i < 100; i++)
if (a[i]) {
ed = i;
break;
}
for (int i = st; i >= ed; i--) {
if (i == 49)
printf(".");
printf("%d", a[i]);
}
printf("\n");
}
return 0;
}</span>
这个题,其实有最偷懒的方法。我们可以找到最高位,从最高位开始,尝试该位能否减掉对应的基数的幂次,直到待分解的数减为0结束。
当然,这样会有很大的精度误差,这个时候就要乱搞了,可以用long double一试,对应的函数也要开long double形式。
在这种情况下,最需要注意的是精度问题。此处的精度必须为1e-10。原因嘛。。。试出来的。
代码如下:
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#define double long double
using namespace std;
const double EPS = 1e-10;
double base = ((double)1.0 + sqrtl((double)5.0)) / (double)2.0;
int dcmp(double x)
{
if(fabs(x) < EPS)
return 0;
else if(x > 0) return 1;
else return -1;
}
int main(void)
{
//freopen("in.txt","r",stdin);
//freopen("out2.txt","w",stdout);
double a;
while(cin>>a){
if(dcmp(a - (double)1.0) == 0){
puts("1");
continue;
}
int l = log10l(a) / log10l(base);
while(a > EPS){
if(dcmp(a - powl(base,l)) >= 0){
putchar('1');
a -= powl(base,l);
}
else
putchar('0');
l--;
if(l == -1) putchar('.');
}
puts("");
}
return 0;
}