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

        歡迎訪問 生活随笔!

        生活随笔

        當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

        编程问答

        CodeForces - 1110G Tree-Tac-Toe(博弈+构造)

        發(fā)布時間:2024/4/11 编程问答 33 豆豆
        生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1110G Tree-Tac-Toe(博弈+构造) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

        題目鏈接:點擊查看

        題目大意:給出一棵樹狀棋盤,棋盤上初始時可能為空也可能為白色,小黑和小白輪流操作,每次操作小黑可以選擇一個空位置染成黑色,小白可以選擇一個空位置染成白色,勝利規(guī)則和五子棋類似,有三個自己的顏色連成一條線即可勝利,問小白先手,兩人依次選擇最優(yōu)方法下棋,最后是白色勝利,黑色勝利,還是平局

        題目分析:首先我們必須知道,因為初始時的局面,加上小白先手,所以小黑必不可能勝利,假設(shè)有一個點可以讓小黑成為必勝點,但小白是先手,肯定會先小黑一步去占領(lǐng)那個位置,所以小黑必不可能勝利,這樣我們只需要分析什么時候小白必勝,剩下的局面肯定都是平局了

        這里掛一個大佬的博客,我覺得分析的相當透徹了:

        https://www.cnblogs.com/Itst/p/10356243.html

        總結(jié)一下小白可以必勝的點就是:

      1. 至少有一個點的度為4
      2. 至少有一個點的度為3,且其至少有兩個度為2的子節(jié)點
      3. 兩端兩個度為3的點,中間由奇數(shù)個點組成的單鏈連接而成
      4. 然后就是如何預處理棋盤上初始化的白色點,我們可以將其轉(zhuǎn)化一下,這里借個圖:

        點1為白色節(jié)點,我們可以將其視為點A,然后連接下面的點B點C與點D

        為什么可以這樣構(gòu)造呢?因為假設(shè)小白在點A處染白了,小黑下一步只能在點B處染色,這樣一來點B,點C和點D對游戲已經(jīng)毫無影響了,相當于讓小白多下了一步,也達到了初始時該點即為白色的條件

        那么如果小黑不在點B染色呢??如果小黑不在B點染色的話,小白接下來就會在B點染色,再然后小黑就會面臨必輸?shù)木置?#xff0c;所以聰明的小黑肯定會選擇在點B染色的

        這個題目主要是比較難構(gòu)造,以及小白必勝的條件分析不全,所以導致莫名其妙的WA,看了題解后才知道這個題目只有三種狀態(tài)需要討論,算是積累知識吧

        還有一點需要提一下,這個題目不能用vector當鏈表用,會T掉,只能老老實實用數(shù)組模擬鏈表來實現(xiàn),并且初始化的時候要將數(shù)組開大到兩倍,因為剛才我們轉(zhuǎn)換白點的關(guān)系,每個初始為白色的點可能需要和一個新點(點B)建立新邊,但點C和點D就不需要真實存在了,在建立好點B后,我們只需要將點B的入度視為3即可

        就這樣吧,剩下的就是實現(xiàn)上述的結(jié)論了,上代碼:

        #include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e6+100;int n;int tot;int node[N];int head[N];int nex[N];int in[N];void addedge(int u,int v) {node[tot]=v;nex[tot]=head[u];head[u]=tot++;node[tot]=u;nex[tot]=head[v];head[v]=tot++;in[u]++;in[v]++; }bool check() {int ans=0;//記錄有多少個入度為3的節(jié)點 for(int i=1;i<=n;i++){if(in[i]>=4)return true;if(in[i]==3){int cnt=0;//記錄有多少個有兒子的節(jié)點for(int j=head[i];j!=-1;j=nex[j]){int u=i;int v=node[j];if(in[v]>=2)cnt++;} if(cnt>=2)return true;ans++;}}if(ans==2&&(n&1))return true;return false; }void init() {tot=0;for(int i=1;i<=n;i++){head[i]=-1; in[i]=0;} }int main() { // freopen("input.txt","r",stdin);int w;cin>>w;while(w--){scanf("%d",&n);init();for(int i=1;i<n;i++){int a,b;scanf("%d%d",&a,&b);addedge(a,b);}string s;cin>>s;if(n<=2){cout<<"Draw"<<endl;continue;}else if(n==3){int cnt=0;for(int i=0;i<s.size();i++)if(s[i]=='W')cnt++;if(cnt>=2)cout<<"White"<<endl;elsecout<<"Draw"<<endl;continue;}for(int i=0;i<s.size();i++){if(s[i]=='W'){++n;head[n]=-1;addedge(i+1,n);in[n]=3;}}if(check())cout<<"White"<<endl;elsecout<<"Draw"<<endl;}return 0; }

        ?

        總結(jié)

        以上是生活随笔為你收集整理的CodeForces - 1110G Tree-Tac-Toe(博弈+构造)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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