hdu1538博弈论-海盗分金-博弈入门


0)觉得博弈游戏蛮有意思的,这算是第一个题把。

1)AC代码。

思路,对于每一个海盗来说,优先性由高到低依次为,保命,得金,杀人。所以可能为了保命、得金、杀更多人而支持或反对决策者。第一种情况时,金子足够,第二种是金子不够、决策者自己不要金子去贿赂别人而保住命且没有人会死,第三种情况是金子不够、决策者不要金子去贿赂别人但依然会死,支持他的人(不支持自己也是必死)也可能会死。

#include <iostream>
#include <math.h>
#include <string.h>

using namespace std;
int main()//先看决策者处在什么位置做什么决策,再看p是决策中的哪一部分
{
    int res;
    int kase;cin>>kase;
    while(kase--){
        res=-1;
        int n,m,p;cin>>n>>m>>p;
        if(n<=2*m){//金子足够时,决策者自己可以分到金子,没有人会死
            if(n==p){
                if(p%2==0)//这四行可以用res=m-(n-1)/2代替
                    res=m-n/2+1;
                else
                    res=m-n/2;
            }//p小于n,且不是决策者而是被贿赂,且与决策者奇偶性相同可得1金
            else if(n%2==p%2){
                res=1;
            }
            else{//p小于n,不是决策且也没有被贿赂,但决定不影响全局
                res=0;
            }
        }
        else if(n==2*m+1||n==2*m+2){//金子不够,决策者自己分不到,没有人会死
            if(n==p){//决策者分不到
                res=0;
            }//剩下的是p小于n,不是决策者,与决策者奇偶性相同可得1金
            else if(n%2==p%2){
                res=1;
            }
            else{//只有p==n,p==2*m+1,这一种情况,该p不被贿赂,其决定不影响全局
                res=0;
            }
        }
        else{//金子不够,可能有人会死

            for(int k=2;k<=120;k++){
               int Temp_Res=2*m+pow(2,k);
                if(Temp_Res==n){//决策者可以保命,那么自然没有人会死
                    res=0;
                    break;
                }
                else if(Temp_Res>n){//决策者必死
                    if(p>2*m+pow(2,k-1)){//必死的人
                        res=-3;//必死的人
                    }
                    else{
                        res=0;//不死的人,是2*m之后的上一个决策者g以及支持他才能不死的人和他之前的不支持他的人
                    }
                    break;
                }
            }

        }
        if(res==-3)
            cout<<"Thrown"<<endl;
        else
            cout<<res<<endl;
    }
    return 0;
}


2)WA代码,第一次WA是因为考虑了金子足够和金子不够但是得到金子就支持决策者得不到就不支持的两种情况,看了下面这位大神代码前的思路(http://blog.csdn.net/acm_cxlove/article/details/7853916#comments)醒悟还有第三种情况,虽然得不到金子,但是自己如果不支持决策者自己也必死因而选择了支持决策者的情况。编写时疑问,当出现第三种情况时,决策者用于贿赂的金子贿赂收贿的人每人1金则刚好自己不死,但是收贿人是不确定的,虽然不用贿赂自己也不用贿赂不支持自己就会必死的人,但是剩下的人也是多于可以贿赂的金子的,姑且按从前往后的顺序选择贿赂对象,提交,又WA,然后看了一遍上面大神博客上的代码,想起题目中 The output for each case consists of a single integer which is the minimal number of gold pieces pirate p can get. For example, if pirate p can get 0 or 1 gold pieces, output '0'.这句话,原来不确定就是输出0,去掉第三种情况中多分析的情况,才AC,下面是第二次WA的代码

#include <iostream>
#include <math.h>
#include <string.h>

using namespace std;
int main()//先看决策者处在什么位置做什么决策,再看p是决策中的哪一部分
{
    int res;
    int kase;cin>>kase;
    while(kase--){
        res=-1;
        int n,m,p;cin>>n>>m>>p;
        if(n<=2*m){//金子足够时,决策者自己可以分到金子,没有人会死
            if(n==p){
                if(p%2==0)//这四行可以用res=m-(n-1)/2代替
                    res=m-n/2+1;
                else
                    res=m-n/2;
            }//p小于n,且不是决策者而是被贿赂,且与决策者奇偶性相同可得1金
            else if(n%2==p%2){
                res=1;
            }
            else{//p小于n,不是决策且也没有被贿赂,但决定不影响全局
                res=0;
            }
        }
        else if(n==2*m+1||n==2*m+2){//金子不够,决策者自己分不到,没有人会死
            if(n==p){//决策者分不到
                res=0;
            }//剩下的是p小于n,不是决策者,与决策者奇偶性相同可得1金
            else if(n%2==p%2){
                res=1;
            }
            else{//只有p==n,p==2*m+1,这一种情况,该p不被贿赂,其决定不影响全局
                res=0;
            }
        }
        else{//金子不够,可能有人会死

            for(int k=2;k<=120;k++){
               int Temp_Res=2*m+pow(2,k);
                if(Temp_Res==n){//决策者可以保命,那么自然没有人会死
                    if(p<=2*m){//此处从前往后取人,这里我觉得从后几个人里倒着往前取人也是可以的,怀疑这里得到金子的人实际上有不确定性
                        if(p%2!=k%2)
                            res=1;
                        else if(p%2==k%2)
                            res=0;
                    }
                    else{
                        res=0;
                    }
                    break;
                }
                else if(Temp_Res>n){//决策者必死
                    if(p<=2*m){//有可能获得1金或0的人
                        if(p%2!=(k-1)%2)//分金情况同上一个有资格不死的决策者g(假定g)做决策相同,其之前的人都会死直到上一个决策者g来分金
                            res=1;
                        else if(p%2==k%2)
                            res=0;
                    }
                    else if(p>2*m+pow(2,k-1)){//必死的人
                        res=-3;//必死的人
                    }
                    else{
                        res=0;//不死的人,是2*m之后的上一个决策者g以及支持他才能不死的人和他之前的不支持他的人
                    }
                    break;
                }
            }

        }
        if(res==-3)
            cout<<"Thrown"<<endl;
        else
            cout<<res<<endl;
    }
    return 0;
}


你可能感兴趣的:(入门,HDU,博弈)