[poj] 1090 Chain

来源:互联网 发布:潮流相机软件 编辑:程序博客网 时间:2024/05/21 21:38

[poj] 1090 Chain

【题目】http://poj.org/problem?id=1700

【题意】求开锁最少步骤

【算法】递归

【题解】首先按照题意写了一个递归程序,是超时的。但发现了一个规律,就是若修改第N个节点值时,从0到N-1都为0时要花费2个N次方-1次操作。于是从尾到首少秒一次数据串,第几数次遇到的1对应要花费的步骤,第偶数次遇见的1对应节约的步骤。还有N为1000,最大结果(2的1000次方-1)为大数,所以用java大数完成。

【注意】普通递归会超时,但是有助于我们发现规律。

超时代码:

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

 

int a[1000];

int ans;

 

void dg(int i,int x){

    if(i<0||a[i]==x) return;

    ans++;

    a[i]=x;

    dg(--i,1);

    for(i--;i>=0;i--)dg(i,0);

}

 

int main(){

    int n,i;

    while(scanf("%d",&n)!=EOF){

        for(i=0;i<n;i++)scanf("%d",&a[i]);

        ans=0;

        for(i=n-1;i>=0;i--)dg(i,0);

        printf("%d\n",ans);

    }

    return 0;

}

【测试数据】

4

1 0 1 0

10

1 0 0 0 0 0 0 0 0 1

10

0 0 0 0 0 0 0 0 1 1

10

0 0 0 0 0 0 0 1 1 1

10

0 0 0 0 0 0 1 1 1 1

10

0 1 0 0 0 0 0 0 0 1

 

 

ans:

6

1022

512

767

640

1020

【AC代码】

import java.io.*;

import java.util.*;

import java.math.*;

 

public class Main{

    public static void main(String[] args){

        Scanner in = new Scanner(System.in);

        BigInteger a;

        int[] s = new int[1000];

        int n,i,f;

        while(in.hasNext()){

            n = in.nextInt();

            for(i=0;i<n;i++)s[i]=in.nextInt();

            a=BigInteger.ZERO;

            f=1;

            for(n--;n>=0;n--)

            if(s[n]==1){

                if(f==1){

                    a=a.add(new BigInteger("2").pow(n+1).subtract(BigInteger.ONE));

                    f=0;

                }

                else{

                    a=a.subtract(new BigInteger("2").pow(n+1).subtract(BigInteger.ONE));

                    f=1;

                }

            }

            System.out.println(a);

        }

 

    }

}

【心得】我要不断提高效率!