zoukankan      html  css  js  c++  java
  • HDU 1847 Good Luck in CET4 Everybody!

    Good Luck in CET-4 Everybody!

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3352    Accepted Submission(s): 2099

    Problem Description
    大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此。当然,作为在考场浸润了十几载的当代大学生,Kiki和Cici更懂得考前的放松,所谓“张弛有道”就是这个意思。这不,Kiki和Cici在每天晚上休息之前都要玩一会儿扑克牌以放松神经。 “升级”?“双扣”?“红五”?还是“斗地主”? 当然都不是!那多俗啊~ 作为计算机学院的学生,Kiki和Cici打牌的时候可没忘记专业,她们打牌的规则是这样的: 1、  总共n张牌; 2、  双方轮流抓牌; 3、  每人每次抓牌的个数只能是2的幂次(即:1,2,4,8,16…) 4、  抓完牌,胜负结果也出来了:最后抓完牌的人为胜者; 假设Kiki和Cici都是足够聪明(其实不用假设,哪有不聪明的学生~),并且每次都是Kiki先抓牌,请问谁能赢呢? 当然,打牌无论谁赢都问题不大,重要的是马上到来的CET-4能有好的状态。
    Good luck in CET-4 everybody!
     
    Input
    输入数据包含多个测试用例,每个测试用例占一行,包含一个整数n(1<=n<=1000)。
     
    Output
    如果Kiki能赢的话,请输出“Kiki”,否则请输出“Cici”,每个实例的输出占一行。
     
    Sample Input
    1 3
     
    Sample Output
    Kiki Cici
     
    Author
    lcy
     
    Source
     
    Recommend
     
    题意:博弈的SG问题求解是通法,可是还没有学会,推了一下,猜想一下居然过了。
     
    1 win
    2 win
    3 lost
    4 win
    5 win
    6 lost
    7 win
    8 win
    9 lost
    10 win
    11 win
    12 lost
    13 win
    14 win
    15 lost
    16 win
    17 win
    18 lost
    把lost的找出来3 6 9 12 15 18额额,3 的倍数。
     
    由于数字的增长是有规律的,1 2 4 8 16 32.....所以,这样的结论也是可以的。一直想找一个特殊情况,打破的这样的3倍数的情况,先试一试。。。。
    居然过了
     
     
    代码:
     
     
    #include<stdio.h>
    int main()
    {
        int k,n;
        while(scanf("%d",&n)>0)
        {
            k=n%3;
            if(k==0)
                printf("Cici\n");
            else printf("Kiki\n");
        }
        return 0;
    }

    SG博弈求解的王道。

    关键是对SG的求解,直接吧所有的情况打表。sg的值为0的时候,奇异状态,输,否则赢。

    给出几个例子说明。贴别人牛人的博客。

    Ø g(0)={},G(0)={0, 1, …},f(0)=0;

    Ø g(1)={},G(1)={0, 1, …},f(1)=0;

    Ø g(2)={#(0)}={f(0)}={0},G(2)={1, 2, …},f(2)=1;

    Ø g(3)={#(1)}={f(1)}={0},G(2)={1, 2, …},f(3)=1;

    Ø g(4)={#(2), #(1, 1)}={f(2), f(1)+f(1)}={1, 0},G(4)={2, 3, …},f(4)=2;

    Ø g(5)={#(3), #(1, 2)}={f(3), f(1)+f(2)}={1, 1},G(5)={0, 2, 3, …},f(5)=0;

    Ø g(6)={#(4), #(1, 4), #(2, 2)}={2, 1, 0},G(6)={3, 4, …},f(6)=3;

    Ø g(7)={#(4), #(1, 4), #(2, 3)}={2, 2, 0},G(7)={1, 3, 4, …},f(7)=1;

    G 图2所示的局面S=(7, 3, 3),有#S=f(7)+f(3)+f(3)=1+1+1=1,故S胜。

    G 游戏C的初始局面S=(3, 4, 6),有#S=1+2+3=01+10+11=0,故S负。

     

    步骤:

     

    2 此类搏弈游戏的一般性解法:

     

    F 用一个n元组(a1, a2, …, an),来描述游戏过程中的一个局面。

     

    F 用符号#S,表示局面S所对应的二进制数。

     

    F 用符号$(x),表示局面(x)的下一步所有可能出现的局面的集合。

     

    F 定义集合g(x):设$(x)={S1, S2, …, Sk},则g(x)={#S1, #S2, …, #Sk}。

     

    F 令非负整数集为全集,集合G(x)表示集合g(x)的补集。

     

    F 定义函数f(n):f(n)=min{G(n)},即f(n)等于集合G(n)中的最小数。

     

    F 设局面S=(a1, a2, …, an),#S=f(a1)+f(a2)+…+f(an),采用二进制数的加法。

     

    感觉有些繁琐,结合代码分析一下

    {

    1.首先我们要求出下一个局面可能出现的情况,

    2.对应的SG值进行用数组标记.

    3.找出最小的值。
    }

     

    代码:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    int hash[1001],SG[1001];
    int arry[12]={12,1,2,4,8,16,32,64,128,256,512,1024};
    void getsg()
    {
        int tmp,i,j;
        for(i=0;i<=1000;i++)
        {
            memset(hash,0,sizeof(hash[0]));//对每一个sg[i]的值,都要用到
            for(j=1;j<arry[0];j++)
            {
                if(arry[j]>i) //判断是否是下一个局面
                    break;
                tmp=i-arry[j];
                hash[SG[tmp]]=1; //对应的g(5)={#(3), #(1, 2)}={f(3),f(1)+f(2)}={1, 1},f(5)=0;
                                                      //f(n)就是SG[i].
            }
            for(j=0;;j++) // 找出最小的。
                if(hash[j]==0)
                {
                    SG[i]=j; //此次不能认为可以是SG[i]=1;因为上面hash[SG[tmp]]=1要用到。
                    break;
                }
        }
    }        
    int main()
    {
        int k,n;
        memset(SG,0,sizeof(SG[0]));
        getsg();
        while(scanf("%d",&n)>0)
        {
            k=SG[n];
            if(k==0)
                printf("Cici\n");
            else printf("Kiki\n");
        }
        return 0;
    }
  • 相关阅读:
    WPF自定义RoutedEvent事件代码段
    微信聊天和通讯录按钮样式
    【转】c#、wpf 字符串,color,brush之间的转换
    模块式开发
    通过属性进行浅拷贝
    【转】string.Format对C#字符串格式化
    酷学习笔记——前言
    C# 连蒙带骗不知所以然的搞定USB下位机读写
    C# Ioc、DI、Unity、TDD的一点想法和实践
    虹软人脸识别速度测试征集
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3106567.html
Copyright © 2011-2022 走看看