1. 程式人生 > >【CodeForces - 299C 】Weird Game (思維,模擬,貪心,博弈,OAE思想)

【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
0001

Output

First

Input

3
110110
001001

Output

First

Input

3
111000
000111

Output

Draw

Input

4
01010110
00101101

Output

First

Input

4
01100000
10010011

Output

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 ;
 }