许多人一定很熟悉九连环(如下图),九个环被串在一起,操作规则如下:第一个(右边)环可以任意装卸,如果第k个环没有被卸掉,而第k个环前边(右边)的所有环都被卸掉,则第k+1个环(第k个环左边的环)可以任意装卸(如果存在的话)。
用0表示此换被卸掉,1表示此环没有被卸掉,则九连环的每个状态可以用一个长度为9的二进制串来表示,如:111111001经过一次操作可以变成111111000,也可以变成111111011,111111111经过一次操作可以变成111111110,也可以变成111111101。
任务描述:
你现在要操作的是一个n连环,n为正整数,给出n连环的两种状态,计算出从第一种状态变换到第二种状态所需要的最少步数。
输入描述
第一行是一个正整数m,表示有m组测试数据。
每组测试数据一共3行,第一行是一个正整数n (0
输出描述
对于每一组测试数据输出一行,一个非负整数,表示从第一种状态变换到第二种状态所需要的最少步数。
输入例子
2 3 0 0 0 1 0 0 4 1 0 0 0 0 1 1 0
输出例子
7 11
代码如下:
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std;
int s[1000],t[1000],f[200][200],ht[200],hs[200];
char str[2][205];
int main()
{
int text;
scanf("%d",&text);
memset(f,0,sizeof(f));
f[1][199]=1;
for(int i=2;i<=128;i++)
{
for(int j=199;j>=1;j--)
{
f[i][j]=f[i-1][j]*2;
}
for(int j=199;j>=1;j--)
if(f[i][j]>9)
{
f[i][j-1]+=f[i][j]/10;
f[i][j]%=10;
}
}
while(text--)
{
int n;
scanf("%d",&n);
int sums=0,sumt=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&s[i]);
sums+=s[i];
}
for(int i=1;i<=n;i++)
{
scanf("%d",&t[i]);
sumt+=t[i];
}
for(int i=n;i>=1;i--)
{
sums-=s[i];
sumt-=t[i];
if(sums%2==1)
{
if(s[i]==1)
s[i]=0;
else
s[i]=1;
}
if(sumt%2==1)
{
if(t[i]==1)
t[i]=0;
else
t[i]=1;
}
}
memset(ht,0,sizeof(ht));
memset(hs,0,sizeof(hs));
for(int i=n,j=1;i>=1;i--,j++)
{
if(s[i]==1)
{
for(int k=199;k>=1;k--)
{
hs[k]+=f[j][k];
if(hs[k]>9)
{
hs[k-1]+=hs[k]/10;
hs[k]%=10;
}
}
}
if(t[i]==1)
{
for(int k=199;k>=1;k--)
{
ht[k]+=f[j][k];
if(ht[k]>9)
{
ht[k-1]+=ht[k]/10;
ht[k]%=10;
}
}
}
}
for(int k=199;k>=1;k--)
{
if(hs[k]>9)
{
hs[k-1]+=hs[k]/10;
hs[k]%=10;
}
if(ht[k]>9)
{
ht[k-1]+=ht[k]/10;
ht[k]%=10;
}
}
int w=0;
memset(str,0,sizeof(str));
str[0][0]=str[1][0]='0';
for(int i=1;i<=199;i++)
{
str[0][i-1]=hs[i]+'0';
str[1][i-1]='0'+ht[i];
}
if(strcmp(str[0],str[1])>0)
{
for(int k=199;k>=1;k--)
hs[k]-=ht[k];
for(int k=199;k>=1;k--)
if(hs[k]<0)
{
hs[k-1]--;
hs[k]+=10;
}
}
else
{
for(int k=199;k>=1;k--)
ht[k]-=hs[k];
for(int k=199;k>=1;k--)
if(ht[k]<0)
{
ht[k-1]--;
ht[k]+=10;
}
w=1;
}
if(w==0)
{
int i;
for(i=1;i<=199;i++)
if(hs[i]!=0)
break;
for(;i<=198;i++)
printf("%d",hs[i]);
printf("%d\n",hs[i]);
}
else
{
int i;
for(i=1;i<=199;i++)
if(ht[i]!=0)
break;
for(;i<=198;i++)
printf("%d",ht[i]);
printf("%d\n",ht[i]);
}
}
return 0;
}