【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兩個(gè)人,各有長度為2n的01串,每次輪流在1~2n里選一個(gè)之前雙方?jīng)]選過的位置的數(shù),然后他可以得到他的串里對應(yīng)位置的數(shù)字。 最后AB顯然各得到n個(gè)數(shù)字,他們將其任意排列后做比較。若雙方都是最優(yōu)策略,問你誰會(huì)贏?
解題報(bào)告:
? ? 首先根據(jù)題干分析出,就是看最后誰拿到的1的數(shù)量比較多。
? ? 貪心拿數(shù),如果一個(gè)位置雙方都是1,顯然兩個(gè)人都優(yōu)先選這個(gè),因?yàn)椴幌胱寣Ψ降玫礁嗟?,同時(shí)自己能拿到1。(也就是對于A達(dá)到的效果是A的+1,B的-1)
? ? 拿完雙方都有的1后,分兩種情況:1.此時(shí)A繼續(xù)先手。2.此時(shí)B為先手?。
? ? 根據(jù)OAE思想,1情況相當(dāng)于給你兩個(gè)串此時(shí)的串 沒有AB數(shù)組都為1的位置。2情況相當(dāng)于在1情況的基礎(chǔ)上A這個(gè)玩家手中已經(jīng)有一個(gè)1了。然后分情況討論一下就行了、、? ??
如果A先手,這種情況比較簡單。A接下來考慮的肯定是不讓B拿到更多的1,因此他會(huì)取A為0但B為1的位置,B玩家同理的考慮。所以我們可以等價(jià)成A玩家先拿自己的,B玩家也先拿自己的。(因?yàn)檫@兩種操作對于A達(dá)到的結(jié)果都相當(dāng)于是A的+1,B的不變,對于B達(dá)到的結(jié)果都相當(dāng)于是A的不變,B的+1,所以可以等價(jià)。)最后才是雙方都為0的位置(就無所謂了)。也就是A比較容易贏,所以我們就看啥時(shí)候A能贏,因?yàn)镺AE思想化簡以后,A只要保證1的數(shù)量比他多就好了,,但是B想贏,就必須必A多兩個(gè),因?yàn)锳先手啊,,他可以可以拿完自己的再作為先手把你的一個(gè)也拿走了,,這樣你就GG了,,,還是被逼平。
如果B先手,這種情況比較復(fù)雜,因?yàn)镺AE完了以后是A有一個(gè)的優(yōu)勢,并且是B先手,,所以分析平局的情況就比較復(fù)雜所以我們先分析平局,,容易落下那個(gè)a+2==b的情況(對于附的那個(gè)樣例就過不去),,并且啊別寫成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,對于這個(gè)樣例就過不去(對于原樣例,也就是第六個(gè)樣例,做了一些化簡,,因?yàn)榉凑嗉右恍?,和多加偶數(shù)個(gè)1,都是一樣的答案。。)
4 10010 11011?
網(wǎng)上的一個(gè)優(yōu)質(zhì)代碼:(就是化簡了一些步驟,其實(shí)這種題還是正兒八經(jīng)分析就行了)
#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 ;}?
總結(jié)
以上是生活随笔為你收集整理的【CodeForces - 299C 】Weird Game (思维,模拟,贪心,博弈,OAE思想)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sessmgr.exe - sessmg
- 下一篇: 【CodeForces - 833A】T