【Poj 1832】连环锁

连环锁

Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 1260 Accepted: 403

Description

许多人一定很熟悉九连环(如下图),九个环被串在一起,操作规则如下:第一个(右边)环可以任意装卸,如果第k个环没有被卸掉,而第k个环前边(右边)的所有环都被卸掉,则第k+1个环(第k个环左边的环)可以任意装卸(如果存在的话)。 
用0表示此换被卸掉,1表示此环没有被卸掉,则九连环的每个状态可以用一个长度为9的二进制串来表示,如:111111001经过一次操作可以变成111111000,也可以变成111111011,111111111经过一次操作可以变成111111110,也可以变成111111101。 

任务描述: 
你现在要操作的是一个n连环,n为正整数,给出n连环的两种状态,计算出从第一种状态变换到第二种状态所需要的最少步数。 

Input

第一行是一个正整数m,表示有m组测试数据。 
每组测试数据一共3行,第一行是一个正整数n (0 < n < 128),后两行每一行描述一种状态,n个数(0或1),用空格隔开。 

Output

对于每一组测试数据输出一行,一个非负整数,表示从第一种状态变换到第二种状态所需要的最少步数。

Sample Input

2
3
0 0 0
1 0 0
4
1 0 0 0
0 1 1 0

Sample Output

7
11

Source

Position

http://poj.org/problem?id=1832

Solution

【Poj1090】Chain

看下这道题基本就会做了,一个状态到另一个状态=(一个状态→ 0)-(一个状态→0),加些高精度减法,与比大小即可

Code

// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define MOD 1000000007
#define INF 1e9
using namespace std;
typedef long long LL;
const int MAXN=1010;
inline int max(int &x,int &y) {return x>y?x:y;}
inline int min(int &x,int &y) {return x<y?x:y;}
inline int gi() {
    register int w=0,q=0;register char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')q=1,ch=getchar();
    while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
    return q?-w:w;
}
const int __bmod__=100000;
struct BN{
    int a[100];
    BN(){memset(a,0,sizeof(a));}
    int& operator [](int n){return a[n];}
    void get(int n){
         memset(a,0,sizeof(a));
         a[1]=n;if(a[1])a[0]=1;
         while(a[a[0]+1]){a[a[0]+1]=a[a[0]]/__bmod__;a[a[0]++]%=__bmod__;}
    }
    bool operator <(BN b) const{
        if(a[0]<b[0])return 1;
        if(a[0]>b[0])return 0;
        for(int i=a[0];i>=1;i--){
            if(a[i]>b[i])return 0;
            if(a[i]<b[i])return 1;
        }
        return 0;
    }
    BN operator -(BN b) const{
        BN ans=*this;int q=1;
        if(ans<b)swap(ans,b),q=-1;
        for(int i=1;i<=ans[0];i++){
            ans[i]=ans[i]-b[i];
            if(ans[i]<0){ans[i+1]--;ans[i]+=__bmod__;}
        }
        while(ans[0]&&!ans[ans[0]])ans[0]--;
        for(int i=1;i<=ans[0];i++)ans[i]*=q;
        return ans;
    }
    BN operator +(BN b) const{
        b[0]=max(a[0],b[0]);
        for(int i=1;i<=b[0];i++){
            b[i]+=a[i];
            if(b[i]>=__bmod__){b[i+1]+=b[i]/__bmod__;b[i]%=__bmod__;}
        }
        if(b[b[0]+1])b[0]++;
        return b;
    }
    BN operator *(BN b) const{
        BN ans;
        ans[0]=a[0]+b[0]-1;
        for(int i=1;i<=a[0];i++)
            for(int o=1;o<=b[0];o++){
                int now=i+o-1;
                ans[now]+=a[i]*b[o];
            }
        for(int i=1;i<=ans[0];i++)if(ans[i]>=__bmod__){ans[i+1]+=ans[i]/__bmod__;ans[i]%=__bmod__;}
        if(ans[ans[0]+1])ans[0]++;
        return ans;
    }
    void print(){printf("%d",a[a[0]]);for(int i=a[0]-1;i>=1;i--)printf("%.5d",a[i]);printf("\n");}
}now,f[2],o,t,up,mu;
int a[MAXN];
int main()
{
    freopen("1832.in","r",stdin);
    freopen("1832.out","w",stdout);
    int T=gi();
    while(T--){
        int n=gi();
        for(int x=0;x<2;x++){
            for(int i=n;i>=1;i--)a[i]=gi();
            f[x].get(a[1]),o.get(1-a[1]),t.get(1),up.get(1),mu.get(2);
            for(int i=2;i<=n;i++){
                if(a[i])
                    now=f[x],f[x]=o+t+up,o=now;
                else o=o+t+up;
                t=t*mu+up;
            }
        }
        if(f[0]<f[1])
            (f[1]-f[0]).print();
        else (f[0]-f[1]).print();
    }
    return 0;
}

 

 

转载于:https://www.cnblogs.com/YJinpeng/p/5954062.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值