zoukankan      html  css  js  c++  java
  • vijos 1557:bzoj:1413: [ZJOI2009]取石子游戏

    Description

    在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排。游戏由两个人进行,两人轮流操作,每次操作者都可以从最左或最右的一堆中取出若干颗石子,可以将那一堆全部取掉,但不能不取,不能操作的人就输了。 Orez问:对于任意给出一个初始一个局面,是否存在先手必胜策略。

    Input

    文件的第一行为一个整数T,表示有 T组测试数据。对于每组测试数据,第一行为一个整数n,表示有n堆石子;第二行为n个整数ai,依次表示每堆石子的数目。

    Output

    对于每组测试数据仅输出一个整数0或1。其中1表示有先手必胜策略,0表示没有。

    Sample Input

    1
    4
    3 1 9 4

    Sample Output

    0

    数据范围
    对于30%的数据 n≤5 ai≤105
    对于100%的数据 T≤10 n≤1000 每堆的石子数目≤109
     
     
    静静膜大神题解……
    对于一段区间[L, R], 若L+1到R的石子数固定, 那么使得在这段区间上先手必败的a[L]有且仅有一个.
    设left[i][j]表示, 在[i, j]区间的左边加上left[i][j]这个数后先手必败, right[i][j]的定义类似. 那么最后我们只用看left[2][n]是否等于a[1]就可以了.

    设L = left[i][j - 1], R = right[i][j - 1], X = a[j]. left[i][j]只和L, R, X三个数有关.

    一大波情况分类:

    当R = X时,left[i][j] = 0。

    当X < L且X < R时, left[i][j] = X。

    当R < X <= L时, left[i][j] = X - 1。

    当L <= X < R时,left[i][j] = X + 1。

    X > L且X > R时,left[i][j] = X。

    对于right[i][j]可做同样处理……

    要是不看大神题解绝逼想不到这么神的做法……

    orz Run Towards End:http://www.cnblogs.com/zcwwzdjn/archive/2012/05/26/2519685.html

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int o,p;
    inline int read(){
        p=0;o=getchar();
        while(o<'0'||o>'9') o=getchar();
        while(o>='0'&&o<='9') p=p*10+o-48,o=getchar();
        return p;
    }
    int t,n,a[1000],l[1001][1001],r[1001][1001];
    int main(){
        register int i,j,k;
        t=read();
        while(t--){
            n=read();
            for (i=0;i<n;i++) l[i][i]=r[i][i]=a[i]=read();
            for (k=1;k<n-1;k++)
            for (i=0;i+k<n;i++){
                j=i+k;
                if (a[j]==r[i][j-1]) l[i][j]=0;else
                if ((a[j]>l[i][j-1]&&a[j]>r[i][j-1])||(a[j]<l[i][j-1]&&a[j]<r[i][j-1])) l[i][j]=a[j];else
                if (l[i][j-1]<=a[j]&&r[i][j-1]>a[j]) l[i][j]=a[j]+1;else
                l[i][j]=a[j]-1;
                if (a[i]==l[i+1][j]) r[i][j]=0;else
                if ((a[i]>l[i+1][j]&&a[i]>r[i+1][j])||(a[i]<l[i+1][j]&&a[i]<r[i+1][j])) r[i][j]=a[i];else
                if (l[i+1][j]<=a[i]&&r[i+1][j]>a[i]) r[i][j]=a[i]+1;else
                r[i][j]=a[i]-1;
            }
            if (l[1][n-1]==a[0]) printf("0
    ");else printf("1
    ");
        }
    }
    View Code
  • 相关阅读:
    队列(queue)、优先队列(priority_queue)、双端队列(deque)
    20150720工作总结
    Spring使用远程服务之Hessian
    iBaits中SqlMapClientTemplate的使用
    java中常见的异常类
    java笔试面试中的坑
    java面试中常用的排序算法
    IBatis和Hibernate区别
    单例和多线程
    ThreadLocal
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5152417.html
Copyright © 2011-2022 走看看