【博弈论】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 }

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

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

 

原文地址:https://www.cnblogs.com/SoulSecret/p/8934480.html

时间: 2024-10-11 21:15:53

【博弈论】Multiplication Game的相关文章

POJ2505 A multiplication game[博弈论]

A multiplication game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6028   Accepted: 3013 Description Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 to 9. Stan always starts with p =

POJ2505 A multiplication game 博弈论 找规律

http://poj.org/problem?id=2505 感觉博弈论只有找规律的印象已经在我心中埋下了种子... 题目大意:两个人轮流玩游戏,Stan先手,数字 p从1开始,Stan乘以一个2-9的数,然后Ollie再乘以一个2-9的数,直到谁先将p乘到p>=n时那个人就赢了,而且轮到某人时,某人必须乘以2-9的一个数. 题目大意来源http://blog.csdn.net/jc514984625/article/details/71157698 因为谷歌翻译太难懂了,所以总是找题解找题目大

「POJ2505」A multiplication game [博弈论]

题目链接:http://poj.org/problem?id=2505 题目大意: 两个人轮流玩游戏,Stan先手,数字 p从1开始,Stan乘以一个2-9的数,然后Ollie再乘以一个2-9的数,直到谁先将p乘到p>=n时那个人就赢了,而且轮到某人时,某人必须乘以2-9的一个数. 解题思路: 这是一道博弈论的题目.不过这道题并没有用SG函数相关的知识.首先我们可以很快判断区间[2,9]必定是先手胜然后紧接着是区间[10,18]区间是后手胜然后是什么呢?[18,??]我们可以这样来理解:我们可以

Multiplication Game(博弈论)

Description 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≥2N≥2 , and an integer M=1M=1. Alice and Bob take

HDU 1517 A Multiplication Game(博弈论)

题目地址:HDU 1517 NP状态转换. 可以把题目的向上乘变成向下除.这样1是终结状态,设1的时候为必败点. 根据所有能一步到达必败点的点是必胜点,所以[x,x*9]必胜点:根据只能到达必胜点的点是必败点,所以[x*9+1,x*9*2]是必败点. 然后求解. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdli

Part.4【博弈论】

---恢复内容开始--- 不要问我为什么突然跳到Part.4,我懒得解释. 在蔡大神的论文+讲解和HZW的题库下,自己大概是明白什么是博弈论的皮毛了吧. 先说SG定理吧. 对于游戏中的状态,我们给每个状态定义一个必胜态和必败态.区别在于前者可以通过一次操作到达必败态,但后者无法做到(后者在一次操作后所能到达的状态全部都为必胜态) 接着引进SG函数,每个状态都有一个SG值,这个值由它所能到达的状态的SG值决定.(这里的所能到达的状态指的是经过一次操作能到达的状态,下同) SG值有以下性质: SG值

博弈论(转)

有一种很有意思的游戏,就是有物体若干堆,可以是火柴棍或是围棋子等等均可.两个人轮流从堆中取物体若干,规定最后取光物体者取胜.这是我国民间很古老的一个游戏,别看这游戏极其简单,却蕴含着深刻的数学原理.下面我们来分析一下要如何才能够取胜. (一)巴什博奕(Bash Game):只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜. 显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜.因此我们发

POJ【数论/组合/博弈论】

 POJ[数论/组合/博弈论]题目列表 POJ[数论/组合/博弈论]题目列表 原来的列表比较水,今天换了一个难一些的列表,重新开始做~ 红色的代表已经AC过,蓝色的代表做了但是还没过.这句话貌似在我空间里的每份列表里都有额. 博弈论 POJ 2234 Matches Game POJ 2975 Nim POJ 2505 A multiplication game POJ 1067 取石子游戏 POJ 2484 A Funny Game POJ 2425 A Chess Game POJ 29

博弈论类题目小结——转载

出处http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 首先当然要献上一些非常好的学习资料: 基础博弈的小结:http://blog.csdn.net/acm_cxlove/article/details/7854530 经典翻硬币游戏小结:http://blog.csdn.net/acm_cxlove/article/details/7854534 经典的删边游戏小结:http://blog.csdn.net/acm