开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情
Codeforces Round #839 (Div. 3)——E. Permutation Game
Problem - E - Codeforces
Two players are playing a game. They have a permutation of integers 11, 22, ..., nn (a permutation is an array where each element from 11 to nn occurs exactly once). The permutation is not sorted in either ascending or descending order (i. e. the permutation does not have the form 1,2,…,n or n,n−1,…,1).
Initially, all elements of the permutation are colored red. The players take turns. On their turn, the player can do one of three actions:
- rearrange the elements of the permutation in such a way that all red elements keep their positions (note that blue elements can be swapped with each other, but it's not obligatory);
- change the color of one red element to blue;
- skip the turn.
The first player wins if the permutation is sorted in ascending order (i. e. it becomes 1,2,…,n). The second player wins if the permutation is sorted in descending order (i. e. it becomes n,n−1,…,1). If the game lasts for 100500100500 turns and nobody wins, it ends in a draw.
Your task is to determine the result of the game if both players play optimally.
Input
The first line contains a single integer tt (1≤t≤1051≤t≤105) — the number of test cases.
The first line of each test case contains a single integer nn (3≤n≤5⋅1053≤n≤5⋅105) — the size of the permutation.
The second line contains nn integers p1,p2,…,pnp1,p2,…,pn — the permutation itself. The permutation pp is not sorted in either ascending or descending order.
The sum of nn over all test cases does not exceed 5⋅1055⋅105.
Output
For each test case, print First if the first player wins, Second if the second player wins, and Tie if the result is a draw.
Example
input
4
4
1 2 4 3
3
2 3 1
5
3 4 5 2 1
6
1 5 6 3 2 4
output
First
Tie
Second
Tie
问题解析
题目是说有一个长度为n的数组,初始既不升序也不降序,两个人轮流对数组操作,每次可以选择把一个数变成可移动状态,或者对所有可移动状态的数进行任意摆放,或者什么也不做。第一个人要把数组变成升序的样子,第二个人要把数组变成降序的样子,问谁先赢,或者只能平局。
如果要把数组变成升序的样子,那么最快速的做法就是把所有需要移动的数都变成可移动状态,再进行一次排序。降序也是一样。
我们可以把需要移动的的数分成三部分:只有升序需要移动的、只有降序需要移动的、两边都需要移动的。他们的数量我们设为a、b、c.
很容易想到,谁先把自己需要的数都变化完了,谁就能赢。
但是也有可能,我们把自己需要的数变化完了,但是最后一个变化的数是两边都需要的,这时候就会给对面做嫁衣了。
想赢,只能是在对面把除c之外的数都变化完之前,我方把自己需要的数+c都变化了,才能赢。剩下的情况就只能是平局了。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
#define endl '\n'
//#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 5e5 + 50, MOD = 998244353;
int a[N], up[N], down[N];
void solve()
{
int n, x = 0, y = 0, z = 0;
cin >> n;
for (int i = 1; i <= n; i++)
{
up[i] = i;
down[i] = n - i + 1;
}
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (a[i] != up[i] && a[i] != down[i])
z++;
else if (a[i] != up[i])
x++;
else if (a[i] != down[i])
y++;
}
if (y - x >= z)
cout << "First" << endl;
else if (x - y > z)
cout << "Second" << endl;
else
cout << "Tie" << endl;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}