日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网-数据结构笔试题目(三)-博弈论圆圈游戏(Circle Game)(附源码)

發(fā)布時(shí)間:2023/12/2 编程问答 83 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客网-数据结构笔试题目(三)-博弈论圆圈游戏(Circle Game)(附源码) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題意

從前有兩個人,一個叫Utkarsh,另外一個叫Ashish。
這兩個人在一個2D的棋盤上玩移動棋子的游戲,一開始從原點(diǎn)出發(fā),Ashish先手。每次可以把棋子向上或者是向右移動k個單位的距離。兩人交替移動,游戲規(guī)定棋子距離原點(diǎn)的距離必須要小于d。當(dāng)有人移動不了棋子的時(shí)候落敗。

現(xiàn)在給出d和k,要求在兩人都智商爆表的情況下,誰會獲勝。

樣例

首先輸入一個整數(shù)t,表示測試數(shù)據(jù)的組數(shù)。接著輸入t行,每行代表一個樣例。每一行輸入兩個整數(shù),

要求輸出勝者的名字。

關(guān)于第一個樣例的解釋:

我們可以發(fā)現(xiàn)當(dāng)兩人輪流執(zhí)行一個回合之后,Ashish一定無路可去,所以勝者是Utkarsh。

題解

一拿到手,我們會很自然地覺得這是一道博弈論的問題。

實(shí)際上看起來也非常像,兩個人輪流游戲,包括游戲的一些細(xì)節(jié),輪流移動,不能移動者落敗,都很符合博弈論問題的特征。從博弈論入手的話,我們會想到必?cái)B(tài)和必勝態(tài)之間的轉(zhuǎn)化。

我們進(jìn)一步分析的話,也不難想到思路。我們把這個平面想象成一個用一個扇形籠罩的區(qū)域,對于靠近扇形邊境上的點(diǎn),只有我們知道了坐標(biāo),就可以計(jì)算出來從原點(diǎn)出發(fā)到達(dá)這里需要的步數(shù),步數(shù)知道了自然也就知道了最終是哪一個人落在了這個點(diǎn)。

這樣我們首先確定下來邊境的勝負(fù)狀況之后,我們就可以逐漸往內(nèi)層倒推,最終求解出原點(diǎn)的狀態(tài)。這個推導(dǎo)的轉(zhuǎn)移非常容易想明白,對于每個點(diǎn)來說它最多只有向右和向上兩條路,對于該點(diǎn)做決策的人來說,只要這兩個決策當(dāng)中有一個能夠到達(dá)自己的必勝態(tài),那么該點(diǎn)自然也是必勝態(tài)。這其實(shí)有點(diǎn)動態(tài)規(guī)劃的思想了,通過這種方法,我們可以求解出平面上每一個能夠達(dá)到的點(diǎn)的狀態(tài)。

看似這個問題就已經(jīng)做完了,非常簡單,但是我們稍微分析一下就會發(fā)現(xiàn)這樣是不行的。道理也很簡單,因?yàn)閺?fù)雜度太大,會超時(shí)。

極端情況下當(dāng)d的量級是1e5,并且k=1的時(shí)候,我們需要考慮的點(diǎn)的數(shù)量應(yīng)該在1e10這個量級,這顯然是不能接受的。那除了這個辦法之外還有其他方法可行嗎?

很多時(shí)候看似問題很難解決,往往是我們走錯了路。我們一直想著怎么遞推,怎么獲取每個點(diǎn)的狀態(tài),其實(shí)一開始這個思路就錯了。這個時(shí)候需要我們把這些念頭放一放,回歸到問題本身。

我們把自己代入先手的玩家,我們會想出什么策略?你會發(fā)現(xiàn)好像一時(shí)半會也沒什么特別好的策略?但如果我們是后手玩家呢?你會發(fā)現(xiàn)好的策略可能沒有,但是賴皮的套路卻是存在的。因?yàn)檫@個扇形是一個四分之一圓,它是對稱的。所以我們可以利用后發(fā)的優(yōu)勢鏡像先手的行動,先手往上我們往右,先手往右我們往上,這樣我們可以保證我們的點(diǎn)始終落在斜對角線。這樣只要先手可以前進(jìn),那么后手就一定可以移動。也就是順著下圖的路線移動。

那這樣豈不是先手必輸嗎?其實(shí)也不是的,也有例外。就是當(dāng)后手無法回到斜線的時(shí)候,也就是說((x+1)k, xk)距離原點(diǎn)小于d,而((x+1)k, (x+1)k)大于d的時(shí)候。

這樣我們就可以很方便寫出代碼:

#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <cmath> #include <cstdlib> #include <string> #include <map> #include <set> #include <algorithm> #include "time.h" #include <functional> #define rep(i,a,b) for (int i=a;i<b;i++) #define Rep(i,a,b) for (int i=a;i>b;i--) #define foreach(e,x) for (__typeof(x.begin()) e=x.begin();e!=x.end();e++) #define mid ((l+r)>>1) #define lson (k<<1) #define rson (k<<1|1) #define MEM(a,x) memset(a,x,sizeof a) #define L ch[r][0] #define R ch[r][1] const int N=1000050; const long long Mod=1000000007;using namespace std;int main() {int t;scanf("%d", &t);rep(z, 0, t) {long long d, k;scanf("%lld%lld", &d, &k);int n = d / (sqrt(2) * k);long long x = (n+1) * k;long long y = n * k;// 判斷是否會出現(xiàn)((x+1)k, xk)可行的情況if (x * x + y * y > d * d) {puts("Utkarsh");}else {puts("Ashish");}}return 0; }

這里有一個小小的坑,就是由于d的范圍是1e5,那么當(dāng)我們計(jì)算距離的時(shí)候由于用到平方會超過int的范圍,所以需要改成long long。

這道題到這里就結(jié)束了,我們也可以看得出來,題目本身是不難的,但是解法沒有那么容易想到。我個人覺得挺有意思的,希望大家也會喜歡。

總結(jié)

以上是生活随笔為你收集整理的牛客网-数据结构笔试题目(三)-博弈论圆圈游戏(Circle Game)(附源码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。