【CodeForces - 299C 】Weird Game (思维,模拟,贪心,博弈,OAE思想)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/84790219

题干:

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

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/84790219