uva 763 斐波拉茨进制问题 RE!!求错点
費氏數列的處理,一向都是相當地費事。當然今天也不例外。各 位應該有聽說過費式數列,或許沒有聽過以費式數列為基底的數字表示法吧!費氏數列基本上就是 (1,1,2,3,5,8,...),定義第零項、第一項都是1,自第二項起,每一項的數值皆等於前兩項的和。接下來我們來考慮費氏進位制: 說得單純一些,就是我們考慮將一個正整數 X 表示成費氏數列當中某些不重複項的和。例如
35 = 1 + 34 = 1 + 13 + 21 = 1 + 5 + 8 + 21 = 1 + 2 + 3 + 8 + 21
看起來有很多種表示法對吧?但若我們規定「選出來的數字不能有相鄰的項」,那麼一切就會變得簡單些了,例如:
35 = 1 + 34
30 = 1 + 8 + 21
28 = 2 + 5 + 21
12 = 1 + 3 + 8
7 = 2 + 5
巧合的是,可以證明恰好只有一種這樣的表示方法。
我們可以用類似二進位數的方法來表達這樣的一個正整數在「費氏進位制」底下長的樣子。
不過,現在費事的地方來了,我們要怎麼樣對兩個「費氏進位」的數字作加法呢?
這就是你的工作,給你兩個以費氏進位制 的數字,你必須把他們加起來,並且用費氏進位制表示出來。
输入说明 :
每兩行為一組測資,每個長度不會超過100個,每組測資以空白隔開
输出说明 :
請輸出結果,並每兩組之間空一行隔開
范例输入 :
10010
1
10000
1000
10000
10000
范例输出 :
10100
100000
100100
我的代码:
#include<cstdio>
#include<cstring>
int ans[1001],a[1001],b[1001];
int l,la,lb;
char s[1001],t[1001];
void fill()
{
memset(ans,0,sizeof(ans));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(t,0,sizeof(t));
}
void init()
{
scanf("%s",t); getchar();
//s->a
la=strlen(s);
for (int i=la;i>=1;i--) a[i]=s[la-i]-'0';
while (!a[la] && la>1) la--;
//t->b
lb=strlen(t);
for (int i=lb;i>=1;i--) b[i]=t[lb-i]-'0';
while (!b[lb] && lb>1) lb--;
}
void find()
{
//a
for (int i=la;i>=1;i--)
if (a[i]>0 && a[i+1]>0) {a[i]--; a[i+1]--; a[i+2]++;}
while (a[la+1])
{
if (a[la]>0 && a[la+1]>0) {a[la]--; a[la+1]--; a[la+2]++;}
la++;
}
//b
for (int i=lb;i>=1;i--)
if (b[i]>0 && b[i+1]>0) {b[i]--; b[i+1]--; b[i+2]++;}
while (b[lb+1])
{
if (b[lb]>0 && b[lb+1]>0) {b[lb]--; b[lb+1]--; b[lb+2]++;}
lb++;
}
//ans
if (la>lb) l=la; else l=lb;
for (int i=1;i<=l;i++) ans[i]=a[i]+b[i];
for (int i=1;i<=l;i++)
while (ans[i]>0 && ans[i+1]>0) {ans[i]--; ans[i+1]--; ans[i+2]++;}
while (ans[l+1])
{
while (ans[l]>0 && ans[l+1]>0) {ans[l]--; ans[l+1]--; ans[l+2]++;}
l++;
}
}
void doit()
{
//first
for (int i=1;i<=l;i++)
{
while (ans[i]>0 && ans[i+1]>0) {ans[i]--; ans[i+1]--; ans[i+2]++;}
while (ans[i]>=2 && i>1) {ans[i+1]++; ans[i-2]++; ans[i]-=2;}
}
while (ans[l+1])
{
while (ans[l]>0 && ans[l+1]>0) {ans[l]--; ans[l+1]--; ans[l+2]++;}
l++;
while (ans[l]>=2 && l>1) {ans[l+1]++; ans[l-2]++; ans[l]-=2;}
}
//ans[0] ans[1] special
if (ans[0]==1) {ans[1]++; ans[0]--;}
if (ans[1]>=2) {ans[2]+=ans[1]/2; ans[1]%=2;}
//second
for (int i=1;i<=l;i++)
{
while (ans[i]>0 && ans[i+1]>0) {ans[i]--; ans[i+1]--; ans[i+2]++;}
while (ans[i]>=2 && i>1) {ans[i+1]++; ans[i-2]++; ans[i]-=2; i=i-2;}
}
while (ans[l+1])
{
while (ans[l]>0 && ans[l+1]>0) {ans[l]--; ans[l+1]--; ans[l+2]++;}
l++;
while (ans[l]>=2 && l>1) {ans[l+1]++; ans[l-2]++; ans[l]-=2;}
}
if (ans[0]==1) ans[1]++;
//output
for (int i=l;i>=1;i--) printf("%d",ans[i]); printf("\n\n");
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while (scanf("%s",s)!=EOF)
{
fill();
init();
find();
doit();
}
return 0;
}