您的位置:首页 > 其它

Codeforces 458A/51nod 1491 黄金系统【思维】好题~

2016-12-09 14:33 447 查看
1491 黄金系统

题目来源: CodeForces

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

q=5√+12,在黄金系统下面a0a1...an等于 ∑ni=0ai∗qn−i ,其中 ai 是0或者1。

现在给出两个黄金系统下面的数字,请比较他们的大小。

Input
单组测试数据。
第一行有一个字符串A。
第二行有一个字符串B。
按照a0到an的顺序输入。
他们都是非空串,可能有前导0,并且只有0和1组成,长度不超过100000。


Output
如果A>B,输出>;
如果A=B,输出=;
如果A<B,输出<;


Input示例
00100
11


Output示例
=


思路:

1、直接求这个结果显然是不可行的(爆LL)。

2、如果我们在纸上稍微写出几个结果,我们不难发现,对应我们设定Qi=1*q^i,那么其满足斐波那契数列。

即Qi=Qi-1+Qi-2.

那么考虑进位问题,对应一个字符串,如果有:ai==0&&ai+1==1&&ai+2==1,那么我们可以进位变成:ai=1,ai+1=0,ai+2=0;

如果我们将一个字符串处理到没法继续进位之后,那么我们接下来只要判定哪个字符串的字典序较大即可(因为有前导0,所以不能直接使用strcmp)。

3、处理进位问题的时候注意要稍加技巧,暴力处理的姿势如果不好,会TLE....(具体参考代码.)

(我们从第一个位子开始枚举,一直枚举到最后,如果当前指针之后两个都是1,表示可以进位,那么对应进位之后,指针向后挪动两个位子,继续判断,如果当前指针位子不能进位了,那么break);

Ac代码:

#include<stdio.h>
#include<string.h>
using namespace std;
char a[100006];
char b[100006];
int main()
{
while(~scanf("%s%s",a+1,b+1))
{
a[0]='0';
b[0]='0';
int lena=strlen(a+1);
int lenb=strlen(b+1);
for(int i=0;i<=lena;i++)
{
for(int j=i;j>=0;j-=2)
{
if(a[j]=='0'&&a[j+1]=='1'&&a[j+2]=='1')
{
a[j+1]='0';
a[j+2]='0';
a[j]='1';
}
else break;
}
}
for(int i=0;i<=lenb;i++)
{
for(int j=i;j>=0;j-=2)
{
if(b[j]=='0'&&b[j+1]=='1'&&b[j+2]=='1')
{
b[j+1]='0';
b[j+2]='0';
b[j]='1';
}
else break;
}
}
if(lena>=lenb)
{
int flag=0;
for(int i=0;i<lena-lenb;i++)
{
if(a[i]>'0')flag=1;
}
if(flag==1)printf(">");
else
{
for(int i=lena-lenb,j=0;i<=lena;i++,j++)
{
if(a[i]==b[j])continue;
if(a[i]>b[j])
{
flag=1;
break;
}
if(a[i]<b[j])
{
flag=2;
break;
}
}
if(flag==0)printf("=");
if(flag==1)printf(">");
if(flag==2)printf("<");
}
printf("\n");
}
else
{
int flag=0;
for(int i=0;i<lenb-lena;i++)
{
if(b[i]>'0')flag=1;
}
if(flag==1)printf("<");
else
{
for(int i=lenb-lena,j=0;i<=lenb;i++,j++)
{
if(a[j]==b[i])continue;
if(a[j]>b[i])
{
flag=1;
break;
}
if(a[j]<b[i])
{
flag=2;
break;
}
}
if(flag==0)printf("=");
if(flag==1)printf(">");
if(flag==2)printf("<");
}
printf("\n");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息