G. Inscryption
根据题意,需要把输入的\(0\)全部转换为\(1\)或\(-1\),使得\(p\over q\)最大。
当\(a[i]=1\)时,\({p \over q}={p'+1 \over q'+1}\)
当\(a[i]=-1\)时,\({p \over q}={p' \over q'-1}\)
通过计算,可知当\(q>2*p+1\)时,\(a[i]=1\)时的收益大于\(a[i]=-1\)时的收益,所以在本题中,将\(0\)转换为\(-1\)的收益一定大于转换为\(1\)的收益。
一开始没有想到局部中的-1数量可能过大,使用当前的\(q\)值减去后缀和的方法判断可行性,会Wa3。
正确做法是直接遍历并贪心,先把全部\(0\)计算为\(-1\),并记录转换的次数\(cnt\),当出现q==0的情况时。把前面转换为-1的其中一个\(0\)变成\(1\),即把\(cnt-1\),再把当前的\(q+2\),\(p+1\),\(cnt=0\),那么就无法计算,输出\(-1\)。
代码
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PII;
const int N = 1e6 + 10;
int t;
int n;
int a[N];
struct node
{
int pos, val;
PII now;
node(int _pos, int _val, PII _now) : pos(_pos), val(_val), now(_now) {}
};
signed main()
{
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> t;
while (t--)
{
cin >> n;
vector<int> turn;
bool judge = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
PII now = {1, 1};
int cnt = 0;
for (int i = 1; i <= n; i++)
{
if (a[i] == 1)
{
now.first++;
now.second++;
}
else if (a[i] == -1)
{
now.second--;
}
else
{
now.second--;
cnt++;
}
if (now.second == 0)
{
if (cnt)
{
cnt--;
now.second += 2;
now.first++;
}
else
{
judge = 1;
break;
}
}
}
if (judge)
{
cout << "-1" << endl;
}
else
{
int tmp = gcd(now.first, now.second);
now.first /= tmp;
now.second /= tmp;
cout << now.first << " " << now.second << endl;
}
}
return 0;
}
标签:PII,cnt,int,GYM,pos,now,over,104128
From: https://www.cnblogs.com/tongluosao/p/17705020.html