连环索

许多人一定很熟悉九连环(如下图),九个环被串在一起,操作规则如下:第一个(右边)环可以任意装卸,如果第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;
 
}

猜你喜欢

转载自blog.csdn.net/u012178728/article/details/81160787