【CodeForces - 299C 】Weird Game (思维,模拟,贪心,博弈,OAE思想)
題干:
Yaroslav, Andrey and Roman can play cubes for hours and hours. But the game is for three, so when Roman doesn't show up, Yaroslav and Andrey play another game.
Roman leaves a word for each of them. Each word consists of?2·n?binary characters "0" or "1". After that the players start moving in turns. Yaroslav moves first. During a move, a player must choose an integer from 1 to?2·n, which hasn't been chosen by anybody up to that moment. Then the player takes a piece of paper and writes out the corresponding character from his string.
Let's represent Yaroslav's word as?s?=?s1s2...?s2n. Similarly, let's represent Andrey's word as?t?=?t1t2...?t2n. Then, if Yaroslav choose number?k?during his move, then he is going to write out character?sk?on the piece of paper. Similarly, if Andrey choose number?r?during his move, then he is going to write out character?tron the piece of paper.
The game finishes when no player can make a move. After the game is over, Yaroslav makes some integer from the characters written on his piece of paper (Yaroslav can arrange these characters as he wants). Andrey does the same. The resulting numbers can contain leading zeroes. The person with the largest number wins. If the numbers are equal, the game ends with a draw.
You are given two strings?s?and?t. Determine the outcome of the game provided that Yaroslav and Andrey play optimally well.
Input
The first line contains integer?n?(1?≤?n?≤?106). The second line contains string?s— Yaroslav's word. The third line contains string?t?— Andrey's word.
It is guaranteed that both words consist of?2·n?characters "0" and "1".
Output
Print "First", if both players play optimally well and Yaroslav wins. If Andrey wins, print "Second" and if the game ends with a draw, print "Draw". Print the words without the quotes.
Examples
Input
2 0111 0001Output
FirstInput
3 110110 001001Output
FirstInput
3 111000 000111Output
DrawInput
4 01010110 00101101Output
FirstInput
4 01100000 10010011Output
Second題目大意:
AB兩個人,各有長度為2n的01串,每次輪流在1~2n里選一個之前雙方沒選過的位置的數,然后他可以得到他的串里對應位置的數字。 最后AB顯然各得到n個數字,他們將其任意排列后做比較。若雙方都是最優策略,問你誰會贏?
解題報告:
? ? 首先根據題干分析出,就是看最后誰拿到的1的數量比較多。
? ? 貪心拿數,如果一個位置雙方都是1,顯然兩個人都優先選這個,因為不想讓對方得到更多的1,同時自己能拿到1。(也就是對于A達到的效果是A的+1,B的-1)
? ? 拿完雙方都有的1后,分兩種情況:1.此時A繼續先手。2.此時B為先手?。
? ? 根據OAE思想,1情況相當于給你兩個串此時的串 沒有AB數組都為1的位置。2情況相當于在1情況的基礎上A這個玩家手中已經有一個1了。然后分情況討論一下就行了、、? ??
如果A先手,這種情況比較簡單。A接下來考慮的肯定是不讓B拿到更多的1,因此他會取A為0但B為1的位置,B玩家同理的考慮。所以我們可以等價成A玩家先拿自己的,B玩家也先拿自己的。(因為這兩種操作對于A達到的結果都相當于是A的+1,B的不變,對于B達到的結果都相當于是A的不變,B的+1,所以可以等價。)最后才是雙方都為0的位置(就無所謂了)。也就是A比較容易贏,所以我們就看啥時候A能贏,因為OAE思想化簡以后,A只要保證1的數量比他多就好了,,但是B想贏,就必須必A多兩個,因為A先手啊,,他可以可以拿完自己的再作為先手把你的一個也拿走了,,這樣你就GG了,,,還是被逼平。
如果B先手,這種情況比較復雜,因為OAE完了以后是A有一個的優勢,并且是B先手,,所以分析平局的情況就比較復雜所以我們先分析平局,,容易落下那個a+2==b的情況(對于附的那個樣例就過不去),,并且啊別寫成a==b+2這樣、、考慮清楚了是誰多。。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e6 + 5; int n; int both,a,b; char s[MAX],t[MAX]; int main() {scanf("%d",&n);n<<=1;scanf("%s",s+1);scanf("%s",t+1);for(int i = 1; i<=n; i++) {if(s[i]=='1' && t[i]=='1') both++;if(s[i] == '1') a++;if(t[i] == '1') b++;}a-=both,b-=both;// 這些都沒用了 int flag = 0;if(both%2==0) {if(a > b) flag = 1;else if(b >= a+2) flag = -1;else flag = 0;} else {if(a+2 == b|| a+1==b) flag = 0;else if(a >= b) flag = 1;else flag = -1;}if(flag == 1) puts("First");if(flag == 0) puts("Draw");if(flag == -1) puts("Second");return 0 ;}如果不寫a+2==b,對于這個樣例就過不去(對于原樣例,也就是第六個樣例,做了一些化簡,,因為反正多加一些0,和多加偶數個1,都是一樣的答案。。)
4 10010 11011?
網上的一個優質代碼:(就是化簡了一些步驟,其實這種題還是正兒八經分析就行了)
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e6 + 5; int n; int both,a,b; char s[MAX],t[MAX]; int main() {scanf("%d",&n);n<<=1;scanf("%s",s+1);scanf("%s",t+1);for(int i = 1; i<=n; i++) {if(s[i]=='1' && t[i]=='1') both++;if(s[i] == '1') a++;if(t[i] == '1') b++;}a-=both,b-=both;if(both%2==1) both=1;else both=0;if(b-1 == both+a) b--;a+=both;if(a>b) puts("First");if(a<b) puts("Second");if(a==b) puts("Draw");return 0 ;}?
總結
以上是生活随笔為你收集整理的【CodeForces - 299C 】Weird Game (思维,模拟,贪心,博弈,OAE思想)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sessmgr.exe - sessmg
- 下一篇: s.exe - s是什么进程 有什么用