A Common Subsequence

只要找到有一个相同的元素输出即可。

AC代码:

const int N = 1010;
int a[N], b[N];
int ans;
int cnt[N];
int main()
{
int t;
sd(t);
while (t--)
{
int n, m, k;
bool flag = 0;
sdd(n, m);
mem(cnt, 0);
rep(i, 1, n)
{
sd(a[i]);
cnt[a[i]]++;
}
rep(i, 1, m)
{
sd(b[i]);
if (cnt[b[i]])
{
flag = 1;
k = 1;
ans = b[i];
}
}
if (flag)
{
puts("YES");
pdd(k, ans);
}
else
puts("NO");
}
return 0;
}

B Sequential Nim

题意:

Codeforces Round #658 (Div. 2)_数组 个石子堆,每个石子堆有 Codeforces Round #658 (Div. 2)_Common_02

这个博弈明显的先手必胜态,因为先手拿的话可以每次都把每堆拿剩下一个,然后下一个拿只能拿最后一个,然后到了最后一堆直接拿完。

考虑一个特殊情况那就是中间出现 Codeforces Round #658 (Div. 2)_数组_03

Codeforces Round #658 (Div. 2)_数组_04这种情况那就在 Codeforces Round #658 (Div. 2)_复杂度_05 这一堆拿三个,然后在 Codeforces Round #658 (Div. 2)_数组_06 这一堆拿 Codeforces Round #658 (Div. 2)_数组_06 个,然后后手只能拿 Codeforces Round #658 (Div. 2)_数组_03

考虑开头连续 Codeforces Round #658 (Div. 2)_数组_03 的个数,如果奇数个 Codeforces Round #658 (Div. 2)_数组_03

再对全为 Codeforces Round #658 (Div. 2)_数组_03

AC代码:

int main()
{
int t;
sd(t);
while (t--)
{
int n, m, k;
int cnt = 0;
sd(n);
rep(i, 1, n)
sd(a[i]);
rep(i, 1, n)
{
if (a[i] == 1)
cnt++;
else
break;
}
if (cnt == n)
{
if (cnt & 1)
puts("First");
else
puts("Second");
}
else
{
if (cnt & 1)
puts("Second");
else
puts("First");
}
}
return 0;
}

C Prefix Flip

题意:

一种操作,可以选择前缀长度为 Codeforces Round #658 (Div. 2)_复杂度_12 ,翻转前 Codeforces Round #658 (Div. 2)_复杂度_12Codeforces Round #658 (Div. 2)_数组_14 值然后顺序再倒一下。要求在 Codeforces Round #658 (Div. 2)_Common_15 步内把给定 Codeforces Round #658 (Div. 2)_复杂度_16 串变成 Codeforces Round #658 (Div. 2)_Common_17 串。
输出任意一种方案数。

既然是任意一种那就找罪容易的一种,每一个都操作,从最后一位往前开始考虑,如果Codeforces Round #658 (Div. 2)_Common_17 串这个位置和 Codeforces Round #658 (Div. 2)_复杂度_16 串 的第一位相同那么就把 Codeforces Round #658 (Div. 2)_复杂度_16 串 的第一位个翻转一下,然后再把当前位置的前缀都翻转,这样这一位就符合了。为了降低复杂度直接记录,Codeforces Round #658 (Div. 2)_Common_21在原序列中跳跃是这样的 Codeforces Round #658 (Div. 2)_Common_22一直到 Codeforces Round #658 (Div. 2)_复杂度_23

举个例子:
Codeforces Round #658 (Div. 2)_数组_24

Codeforces Round #658 (Div. 2)_数组_25

Codeforces Round #658 (Div. 2)_数组_26

Codeforces Round #658 (Div. 2)_数组_27

Codeforces Round #658 (Div. 2)_Common_28

AC代码:

const int N = 1e5 + 50;
int n;
char s1[N], s2[N];
int cnt, res, pos;
vector<int> v;

int main()
{
int t;
sd(t);
while (t--)
{
sd(n);
ss(s1 + 1);
ss(s2 + 1);
v.clear();
cnt = n;
res = 0;
pos = 1;
per(i, n, 1)
{
//pddd(s2[i] - '0',res,(s2[i] - '0') ^ res);
if ((s1[pos] - '0') == ((s2[i] - '0') ^ res)) //每次都翻转前缀和为 n-- 的 这个操作就是代替了翻转的操作
v.pb(1);
v.pb(cnt--);
pos = n - pos + 1;//翻转后的位置.
if (pos <= n / 2)
pos++;
res = 1 - res; //0,1切换
}
printf("%d ", v.size());
for (auto i : v)
printf("%d ", i);
printf("\n");
}
return 0;
}

D Unmerge

题意:

给两个数组的 Codeforces Round #658 (Div. 2)_数组_29 规则,给一个 Codeforces Round #658 (Div. 2)_Common_15 的序列 Codeforces Round #658 (Div. 2)_复杂度_31 ,问是不是两个数组 Codeforces Round #658 (Div. 2)_数组_32 之后的结果。 这个 Codeforces Round #658 (Div. 2)_数组_32

Codeforces Round #658 (Div. 2)_Common_34

Codeforces Round #658 (Div. 2)_Common_35

Codeforces Round #658 (Div. 2)_Common_36 所以先取 Codeforces Round #658 (Div. 2)_Common_37

Codeforces Round #658 (Div. 2)_复杂度_38Codeforces Round #658 (Div. 2)_复杂度_39

Codeforces Round #658 (Div. 2)_Common_40Codeforces Round #658 (Div. 2)_Common_41

Codeforces Round #658 (Div. 2)_复杂度_42Codeforces Round #658 (Div. 2)_数组_43

Codeforces Round #658 (Div. 2)_数组_44Codeforces Round #658 (Div. 2)_数组_45

Codeforces Round #658 (Div. 2)_Common_46Codeforces Round #658 (Div. 2)_数组_47

最后取 Codeforces Round #658 (Div. 2)_数组_48

组成序列 Codeforces Round #658 (Div. 2)_复杂度_49

考虑第一个数 Codeforces Round #658 (Div. 2)_数组_50,则向右第一个比 Codeforces Round #658 (Div. 2)_数组_50 大的数为 Codeforces Round #658 (Div. 2)_Common_52

Codeforces Round #658 (Div. 2)_Common_52

分组以后用 Codeforces Round #658 (Div. 2)_数组_14

AC代码:

const int N = 4e5 + 50;
int n, k, m;
int a[N];
vector<int> ans;
int dp[N];
int tmp, cnt;
int main()
{
int t;
sd(t);
while (t--)
{
mem(dp, 0);
ans.clear();
sd(n);
rep(i, 1, 2 * n)
sd(a[i]);
tmp = a[1];
cnt = 1;
rep(i, 2, 2 * n)
{
if (a[i] < tmp)
cnt++;
else if (a[i] > tmp)
{
ans.pb(cnt);
cnt = 1;
tmp = a[i];
}
}
ans.pb(cnt);
sort(ans.begin(), ans.end());
rep(i, 0, ans.size() - 1)
{
per(j, n, ans[i])
dp[j] = max(dp[j], dp[j - ans[i]] + ans[i]);
}
if (dp[n] == n)
puts("YES"); //刚好装满
else
puts("NO");
}
return 0;
}