zoukankan      html  css  js  c++  java
  • 【博弈论】Multiplication Game

    题目描述

    Alice and Bob are in their class doing drills on multiplication and division. They quickly get bored and instead decide to play a game they invented.
    The game starts with a target integer N≥2, and an integer M = 1. Alice and Bob take alternate turns. At each turn, the player chooses a prime divisor p of N, and multiply M by p. If the player’s move makes the value of M equal to the target N, the player wins. If M > N, the game is a tie.
    Assuming that both players play optimally, who (if any) is going to win?

    输入

    The first line of input contains T (1≤T≤10000), the number of cases to follow. Each of the next T lines describe a case. Each case is specified by N (2≤N≤231-1) followed by the name of the player making the first turn. The name is either Alice or Bob.

    输出

    For each case, print the name of the winner (Alice or Bob) assuming optimal play, or tie if there is no winner.

    样例输入

    10
    10 Alice
    20 Bob
    30 Alice
    40 Bob
    50 Alice
    60 Bob
    70 Alice
    80 Bob
    90 Alice
    100 Bob
    

    样例输出

    Bob
    Bob
    tie
    tie
    Alice
    tie
    tie
    tie
    tie
    Alice

    题目大意:两人轮流用所给数的质因数相乘,先达到所给数的人胜利,可出现平局,即某人的决策只能处于必败态则通过操作使博弈编程平局(我不能赢也不让你赢)amazing

    思路分析:根据唯一解定理,质因数是的数目可分为三种情况分析:质因数只有一种、有两种以及大于三种。

        (1)质因数只有一种:该质因数需要奇数个则先手获胜,若需要偶数个则后手获胜;

        (2)质因数有两种:两种质因数所需数目相同,则后手获胜(不论先手如何操作,后手只需平衡即可);

                   两种质因数所需数目不同,if差值为一,则先手获胜;else原必败态可以通过操作使之平局;

        (3)质因数有三种及三种以上:必然可以通过操作使之达到平局。

      1 #include<bits/stdc++.h>
      2  
      3 using namespace std;
      4 const int mod = 1e9+7;
      5 typedef long long ll;
      6 #define LL long long
      7  
      8 const int maxn = 1e5+100;
      9  
     10 int prime[maxn+1];
     11  
     12 bool vis[maxn];
     13 ll cnt;
     14 void primejudge(int n)
     15 {
     16     cnt=0;
     17     vis[1]=true;
     18     ll i,j;
     19     for(i=2; i<=n; i++)
     20     {
     21         if(!vis[i])
     22         {
     23             prime[cnt++]=i;
     24         }
     25         for(j=0; j<cnt&&i*prime[j]<=n; j++)
     26         {
     27             vis[i*prime[j]]=true;
     28             if(i%prime[j]==0)
     29             {
     30                 break;
     31             }
     32         }
     33     }
     34 }
     35  
     36 int main()
     37 {
     38     primejudge(maxn);
     39     int T;
     40     cin>>T;
     41     while(T--)
     42     {
     43         ll n;
     44         string ss;
     45         cin>>n>>ss;
     46  
     47         int ret = 0;
     48         vector<int>v;
     49         for(int i=0; i<cnt; i++)
     50         {
     51  
     52             if(n%prime[i]==0)
     53             {
     54                 ret++;
     55                 int tmp=0;
     56                 while(n%prime[i]==0)
     57                 {
     58                     n/=prime[i];
     59                     tmp++;
     60                 }
     61                 v.push_back(tmp);
     62             }
     63             if(ret>=3)
     64                 break;
     65         }
     66         if(n>1)
     67         {
     68             ret++;
     69             v.push_back(1);
     70         }
     71         if(ret>=3)
     72         {
     73             cout<<"tie"<<endl;
     74         }
     75         else if(ret==1)
     76         {
     77  
     78             if(v[0]%2==0)
     79             {
     80                 if(ss=="Alice")
     81                     cout<<"Bob"<<endl;
     82                 else
     83                     cout<<"Alice"<<endl;
     84             }
     85             else
     86             {
     87                 if(ss!="Alice")
     88                     cout<<"Bob"<<endl;
     89                 else
     90                     cout<<"Alice"<<endl;
     91             }
     92         }
     93         else if(ret==2)
     94         {
     95  
     96             //cout<<" 2 "<<endl;
     97             if(v[1]==v[0])
     98             {
     99                 if(ss=="Alice")
    100                     cout<<"Bob"<<endl;
    101                 else
    102                     cout<<"Alice"<<endl;
    103             }
    104             else
    105             {
    106                 if(abs(v[0]-v[1])==1)
    107                     if(ss!="Alice")
    108                         cout<<"Bob"<<endl;
    109                     else
    110                         cout<<"Alice"<<endl;
    111                 else
    112                 {
    113                     cout<<"tie"<<endl;
    114                 }
    115             }
    116         }
    117         else
    118         {
    119             cout<<ss<<endl;
    120         }
    121     }
    122  
    123 }
    View Code

    注意:这题开始队友wa了几发,一是数据是1e9的线性筛也无法预处理所有质因数,但是可以考虑只预处理1e5内的质数,因为大于1e5之后最多有且只有一个质因数,否则为它本身;

       但在统计质因数时,仍需考虑一种特例,举例说明吧:若说给数为10000019,该数为质数但大于1e5,可直接ret++,但2*10000019,在统计质因数时要先统计2这个因子,然后因为商不等于一,ret++,同时v.push_back(1)。为什么要push呢,因为要比较质因数的出现次数啊,因为这个数大于1e5,所以它之后出现一次,故push_back(1)。

     
  • 相关阅读:
    hadoop集群配置和测试
    ubuntu 12.04安装jdk
    springboot集成mybatis
    redis连接数据库
    生产随机数
    关于字符串统计次数
    闲的无聊写了一个房租的后台
    简单的死锁
    java集合类总结(转)
    mybatis框架的搭建
  • 原文地址:https://www.cnblogs.com/SoulSecret/p/8934480.html
Copyright © 2011-2022 走看看