取棋子

来源:互联网 发布:java bufferedstream 编辑:程序博客网 时间:2024/04/30 12:38

甲乙两人从N枚棋子中轮流取子,甲先取,规定每次所取的枚数不能多于上一个人所取的枚数,也不可不取。甲第一次取多少枚才能保证甲获胜(取得最后的棋子获胜),当然,他也不能第一次就把所有棋子都取走。

代码如下:

#include <stdlib.h>
#include <iostream>
using namespace std;
#define MAX 100000
int num(int n,int k=0);
int main()
{
    int n,k,m;
    cout<<"请输入不大于"<<MAX<<"的正整数,输入退出"<<endl;
    while(cin>>n&&(n>MAX||n<0))
        cout<<"请重新输入"<<endl;
    if(n==0)
        goto END;    
    m=num(n);
    if(m<0)
        goto END;
    n-=m;
    while(n!=0)
    {
        cout<<"我取走"<<m<<" 剩余:"<<n<<endl<<"请问你取走多少个?"<<endl;
        while(cin>>k&&(k>m||k<0||k>n))
            cout<<"请重新输入"<<endl;
        if(k==0)
            goto END;
        n-=k;
        cout<<"你取走"<<k<<" 剩余:"<<n<<endl;
        if(n==0)
        {
            cout<<"你胜利了!"<<endl;
            goto END;
        }
        m=num(n,k);
        if(m<0)
            goto END;
        n-=m;
    }
    cout<<"我取走"<<m<<" 剩余:"<<n<<endl;
    cout<<"你输了"<<endl;
END:system("pause");
    return 0;
}
int num(int n,int k)
{
    if(n<=k)
        return n;
    int i,t=1;
    while(t<=n)
    {
        t*=2;
    }
    t/=2;
    if(t==n)
    {
        if(k==0)
            cout<<"非必胜"<<endl;
        t=n/2+2;
    }
    else if(k==0)
        cout<<"必胜"<<endl;
    t=n-t;
    if(t>k&&k!=0)
   {
        t=1;
        while(t<=k&&n%t==0)
            t*=2;
        t/=2;
    }
    if(t<1||(k!=0&&t>k)||t>n)
    {
        cout<<"Error:"<<endl<<n<<" "<<k<<" "<<t<<endl;
        return -1;
    }
    return t;
}