A-D
A. GamingForces
一眼题,当有两个怪兽的生命都为1时,使用操作1最优,否则,使用操作2
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6;
int n,a[N];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
cin>>n;
map<int,int>mp;
for(int i=1;i<=n;i++)
{
cin>>a[i];
mp[a[i]]++;
}
cout<<mp[1]/2+n-mp[1]/2*2<<"\n";
}
return 0;
}
B. Stand-up Comedian
若a1为0,则特判答案为1,否则先讲a1个笑话,然后再轮流依次讲a2,a3的笑话,直到a2,a3有笑话被讲完,此时两个观众的兴奋值仍为a1,再讨论讲剩下的笑话和兴奋值。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6;
int n,a1,a2,a3,a4;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
cin>>a1>>a2>>a3>>a4;
if(a1==0)
{
cout<<1<<"\n";
continue;
}
cout<<a1+min(a2,a3)*2+min(a1+1,a2+a3-min(a2,a3)*2+a4)<<"\n";
}
return 0;
}
C. Min Max Sort
序列操作为在全排序序列中取两个数,然后较小者放前面,较大者放最后。
求最小排序序列的次数,观察到,连续上升的序列是不用进行此操作来排序的,
则dp寻找以x结尾连续上升序列的个数,答案ans=max(x-dp[x],n-x),
对每个dp[x]进行更新答案,找到最小的ans。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6;
int n,p[N],dp[N];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
cin>>n;
int ans=1e8;
for(int i=1;i<=n;i++)dp[i]=0;
for(int i=1;i<=n;i++)
{
cin>>p[i];
dp[p[i]]=dp[p[i]-1]+1;
ans=min(ans,max(p[i]-dp[p[i]],n-p[i]));
}
cout<<ans<<"\n";
}
return 0;
}
D. Fixed Prefix Permutations
给出n个长度为m的全排序序列,定义排序p*q为创建一个新排序r
r[i]=q[p[i]]。对于一个序列x来说,beauty值为x[i]=i,连续成立的最大i值。
求每个序列对其他所有序列的p*q的beauty最大值。
使用字典树,对每个序列p来说,有一个最优的序列q,即满足q[p[i]]=i,
将此最优序列q挂上字典树,序列q的q[i]也代表着序列p的大小为i的值
在p序列的第q[i]个位置。
接下来,对每个原排序序列求p*q的beauty最大值,即将原排序序列放在
字典树上求最长前缀,为满足式子r[i]=q[p[i]]=i,依次来看,当i为1时,
即寻找q[p[1]]=1的串是否存在,即在字典树上检查是否存在序列q
有一个大小为p[1]的值在q序列的第1个位置上。
(有点绕,请结合代码打印出最优序列q仔细推敲,
直接在字典树挂原串用最优串来匹配是错误的因为q[p[i]]=i的p[i]不是按顺序的,
有可能跳着,但是原串的第i个又不满足q[p[i]]=i就会出错)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
int n,m,b[20],p[N][15];
struct tire
{
int son[N][26],idx=0;
void insert(int a[])
{
int p=0;
for(int i=1; i<=m; i++)
{
int u=a[i];
if(!son[p][u])son[p][u]=++idx;
p=son[p][u];
}
}
int query(int a[])
{
int p=0,ans=0;
for(int i=1; i<=m; i++)
{
int u=a[i];
if(!son[p][u])return ans;
ans++;
p=son[p][u];
}
return ans;
}
};
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
cin>>n>>m;
tire t;
for(int i=0;i<=n*10;i++)
{
for(int j=0;j<=10;j++)
t.son[i][j]=p[i][j]=0;(结构体变量记得初始化)
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin>>p[i][j];
b[p[i][j]]=j;
}
t.insert(b);
}
for(int i=1; i<=n; i++)
{
cout<<t.query(p[i])<<" ";
}
cout<<"\n";
}
return 0;
}