zoukankan      html  css  js  c++  java
  • HDU_1729 Stone Game(SG)

      这题问了三个人才做出来,晕啊。第一位是位大牛,把基本的思路给我讲清楚了,但是在实现上卡住了,老是想着怎么开个sg[]数组记忆搜过的sg值,后来才发现想错了。第二位,之前被大牛讲明白的gbx,原来这里直接返回s - c的值当作sg值就行,至于为什么,稍后再续。第三位,zz,可以鄙视我了,因为我手贱看他的代码了,不过他的代码确实有值得学习的地方,很简练!

    思路:这题明显的sg函数。可惜我纠结了半天没想起思路来。1、设当前的箱子容量为si,求出一个t满足:t + t * t < si,如果当前箱子里有ci颗石头,

    1、ci > t 则必胜;

    2、ci == t 则必败;

    3、ci < t不能确定,将t作为si递归调用函数。

    当满足ci > t时,return si - ci 作为当前状态的sg值。因为:

    如图:

    当ci在si点时,为有向图的端点,出度为0,也就是必败点,所以sg值为0;

    当ci 位于si - 1时,ci的端点可能的sg值构成的集合为{0},所以当前sg值 为1;

    当ci 位于si - 2 时,ci的端点可能的sg值构成的集合为{0, 1},所以当前的sg值为2;

    可得,ci所在位置的sg值为si - ci;

    My Code:

    #include <iostream>
    #include <cstdio>
    #include <cmath>

    using namespace std;

    int sg(int c, int s){
    int t = sqrt(s); //这里跟zz学的,如果s很大的话可以减少很多计算。
    while(t*t + t >= s) t--;
    if(c > t) return s - c;
    else return sg(c, t);
    }

    int main(){
    //freopen("data.in", "r", stdin);

    int n, c, s, cas = 0, flag;
    while(scanf("%d", &n), n){
    printf("Case %d:\n", ++cas);
    flag = 0;
    while(n--){
    scanf("%d%d", &s, &c);
    flag ^= sg(c, s);
    }
    if(flag) printf("Yes\n");
    else printf("No\n");
    }
    return 0;
    }



  • 相关阅读:
    Asp.net routing vs Url rewriting
    How to combine WCF Route and MVC Route to work together.
    Servlets beat CGI
    What if you encounter a problem when consume your WCF service ? How to Diagnostic it ?
    uva 4965 Sum the Square
    zoj 3633 Alice's present
    4966 Normalized Form
    ZOJ 3015 Collision Ball Game
    二分图 最小路径覆盖
    uva 2696 Air Raid
  • 原文地址:https://www.cnblogs.com/vongang/p/2193375.html
Copyright © 2011-2022 走看看