• 【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("
    ");}
    }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;
    }

     

  • 相关阅读:
    C++类中使用new及delete小例子(续)
    C++类中使用new及delete小例子
    C++类中static修饰的函数的使用
    C++类使用static小例子(新手学习C++)
    C++结构体中使用函数与类中使用函数小结
    记一次简单的性能优化
    [转载]Java的内存回收机制
    写给自己的项目总结
    [转载]正则表达式30分钟入门教程
    使用JRockit进行性能优化一:环境搭建
  • 原文地址:https://www.cnblogs.com/YJinpeng/p/5954062.html
Copyright © 2020-2023  润新知