- A - Common Subsequence
A题就特别简单大水题,找a,b两个数组中是否有相同元素,如果有,输出一个,没了。
int a[1005],b[1005];
void sove()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d",&b[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])
{
printf("YES\n1 %d\n",a[i]);
return;
}
}
}
printf("NO\n");
}
- B - Sequential Nim
B题我吐了想到了写了好久,只要比较前面1的个数然后后面的就不用管了,具体看代码,看不懂仔细想想,先手的人肯定占绝对优势,而前面的1就是让先手的人失去优势的东西。
int a[maxn],b[1005];
void sove()
{
int n;
scanf("%d",&n);
int cnt1=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
if(n==1)
{
printf("First\n");
return;
}
int cnt=0;
for(int i=1;i<=n;i++)
{
if(a[i]==1)
{
cnt++;
}
else
{
break;
}
}
if(cnt==n)//我没特判一直不对,调了半天
{
if(cnt%2==1)
{
printf("First\n");
}
else
{
printf("Second\n");
}
return ;
}
if(cnt%2==1)
{
printf("Second\n");
}
else
{
printf("First\n");
}
}
- B - Prefix Flip (Hard Version)
这一题我也只能说只可意会不可言传了,拿起你的笔对着代码写一遍你就懂了,可能不需要写一遍写个三四个数字就知道了
char a[maxn],b[maxn];
vector<int>ans;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ans.clear();
int n;
scanf("%d",&n);
scanf("%s%s",a+1,b+1);
for(int i=2;i<=n;i++)
{
if(a[i]!=a[i-1])
{
ans.push_back(i-1);
}
}
char last=a[n];
for(int i=n;i>=1;i--)
{
if(last!=b[i])
{
ans.push_back(i);
last=last=='0'?'1':'0';
}
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++)
{
printf("%d ",ans[i]);
}
printf("\n");
}
return 0;
}
- D - Unmerge
这一题我是根本没有想到的,还能这么搞,居然直接转移成01背包了,真厉害,在下实在是佩服,你可以对着样例看看,是不是每出现一个比较大的值,后面一直要到出现比这个值大的数的时候才会停止加入数列a或者数列b中,这样我们把每个单个的这种序列都抽出来他们的大小,然后看是否可以组成n这么大的两个新数列,这个就用01背包完成
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define se second
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 5e5 + 50;
const int maxm = 1.5e5+50;
const double eps = 1e-7;
const double inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const double pi=3.141592653589;
int n,a[4005],dp[4005];
vector<int>ans;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
n=2*n;
ans.clear();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1,j=1;i<=n;i++)
{
j=i;
while(j<=n&&a[i]>=a[j])
{
j++;
}
ans.push_back(j-i);
i=j-1;
}
ms(dp,0);
dp[0]=1;
for(int i=0;i<ans.size();i++)
{
for(int j=n;j>=0;j--)
{
if(j-ans[i]>=0&&dp[j-ans[i]])
{
dp[j]=1;
}
}
}
if(dp[n/2])
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}