程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 1517 A Multiplication Game

HDU 1517 A Multiplication Game

編輯:C++入門知識

 
題意:2 個人玩游戲,給定一個數n,從 1 開始,輪流對數進行累乘一個數(2~9中取),
 
直到第一次等於或超過n為贏.

思路:1)找規律

如果n是 2 ~ 9 ,Stan 必勝。

如果輸入是 10~18 ,不管第一次Stan 乘的是什麼,Stan肯定在 2 ~ 9 之間,

  無論stan乘以什麼,Ollie乘以大於1的數都都能超過 10 ~ 18 中的任何一個數。Ollie 必勝。

如果輸入是 19 ~ 162,那麼這個范圍是 Stan 的必勝態。

如果輸入是 163 ~ 324 ,這是又是Ollie的必勝態。

............

必勝態是有規律可循的。

如果"我方"首先給出了一個在n不斷除18後的得到不足18的

數m,"我方"就可以取得勝利,然而雙方都很聰明,所以這樣勝負就決定於n了,
 
如果n不斷除18後的得到不足18的數m,
 
若1<m<=9則先手勝利,
 
若9<m<=18則後手勝利.
 
[cpp] 
#include<stdio.h> 
int main() 

  double n; 
  while(scanf("%lf",&n)!=EOF) 
  { 
     while(n>18) n/=18; 
     printf(n<=9?"Stan wins.\n":"Ollie wins.\n"); 
  } 
  return 0; 


  2)博弈(給出牛人的解題思路)

先引入必勝點和必敗點兩個概念:

   必敗點(P點) :前一個選手(Previous player)將取勝的位置稱為必敗點。

   必勝點(N點) :下一個選手(Next player)將取勝的位置稱為必勝點。

算法實現:

   步驟1:將所有終結位置標記為必敗點(P點);(終結位置指的是不能將游戲進行下去的位置)

   步驟2:將所有一步操作能進入必敗點(P點)的位置標記為必勝點(N點)

   步驟3:如果從某個點開始的所有一步操作都只能進入必勝點(N點) ,則將該點標記為必敗點(P點) ;

   步驟4:如果在步驟3未能找到新的必敗(P點),則算法終止;否則,返回到步驟2。

解題思路:

   由於每次都是從p=1開始的,所以只要判斷每個游戲中1為必敗點還是必勝點即可。

 (以下各式 / 均為取上整)依照上面所提到的算法,將終結位置,即[n,無窮]標記為必敗點;

   然後將所有一步能到達此必敗段的點標記為必勝點,即[n/9,n-1]為必勝點;

   然後將只能到達必勝點的點標記為必敗點,即[n/9/2,n/9-1]為必敗點;

   重復上面2個步驟,直至可以確定1是必勝點還是必敗點。

[cpp] 
#include <math.h> 
#include <stdio.h> 
int main() 

    unsigned int n,x; 
    while(~scanf("%u",&n)) 
    { 
        for(x=0;n>1;x++) 
        { 
            if(x&1) 
                n = ceil(n*1.0/2); 
            else 
                n = ceil(n*1.0/9); 
        } 
        puts(x&1?"Stan wins.":"Ollie wins."); 
    } 
    return 0; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved