挺离谱的。
A~D 都不是很难,可惜 D 赛后 10 min 就切掉了。
今晚没有打牛客 (我还睡了一觉 qwq)
A - Gold and Silver
比较考验阅读理解能力。
注意换和购入不能同时发生 只能 either 或 neither
所以最简单的方法就是 ^1 。
判断如果 a[i]>a[i+1] 则证明应该第 i 天全部换成银币,第二天再全部换回来(即换成金币),相当于 vis[i]^=1 且 vis[i+1]^=1 。(如果你交换 a[i] 和 a[i+1] 可能会 wa 掉,因为题目说了要保证最后剩的是金币且最多)
#include<bits/stdc++.h>
#define ll long long
#define db double
#define inf 0x3f3f3f3f
using namespace std;
const int N=2e5+5;
int n,a[N],vis[N];
int main() {
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++) {
if(a[i]>a[i+1]) {
vis[i]^=1,vis[i+1]^=1;
}
}
for(int i=1;i<=n;i++) printf("%d ",vis[i]);
}
B - Balls of Three Colors
枚举全排列 a 0 , a 1 , a 2 {a_0,a_1,a_2} a0,a1,a2 。
手玩一下可以发现 ∣ a 0 − a 1 ∣ |a_0-a_1| ∣a0−a1∣ 必须是 3 3 3 的倍数,同时操作次数恰好为 m a x ( a 0 , a 1 ) max(a_0,a_1) max(a0,a1) 。
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int n,a[3],res;
int main() {
int T; cin>>T;
while(T--) {
cin>>a[0]>>a[1]>>a[2];
sort(a,a+3);
res=inf;
do{
if(abs(a[0]-a[1])%3==0) {
res=min(res,max(a[0],a[1]));
}
}while(next_permutation(a,a+3));
if(res==inf) printf("-1\n");
else printf("%d\n",res);
}
}
C - Max Dot
这题稍微要想一下 (但是突破了应该实现不难)
我们考虑当前 max ( a 1 , . . . , a n ) \max(a_1,...,a_n) max(a1,...,an) 的位置。记最大值的位置为 i 。
如果 i = n i=n i=n 的话就直接令 x i x_i xi 取最大值,否则不难发现 x i = x i + 1 x_i=x_{i+1} xi=xi+1。此时定义新贡献为 一段区间的和除以区间长度。可以划归到长度为 n − 1 n-1 n−1 的问题。若 n = 1 n=1 n=1则这个整体都赋 S l 1 \frac{S}{l_1} l1S 即可。
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int n,a[3],res;
int main() {
int T; cin>>T;
while(T--) {
cin>>a[0]>>a[1]>>a[2];
sort(a,a+3);
res=inf;
do{
if(abs(a[0]-a[1])%3==0) {
res=min(res,max(a[0],a[1]));
}
}while(next_permutation(a,a+3));
if(res==inf) printf("-1\n");
else printf("%d\n",res);
}
}
D - Neq Neq
基本思路:固定右端点 i i i ,找满足条件的合法的前继 j < i j<i j<i 。
然后找到 [l,r] 能被消除的充要条件:任意两个点的颜色不相同且颜色个数 >=3 (或者长度 <=3)
这里的 trick 是用不等式来夹逼范围。即分为 j<=i-3 和 i-2<=j<=n-1 两种情况(因为 n=2 或 n=3 时不同颜色数 <=2 也是合法转移)
可以理解成分段函数。
特判贼 jb 恶心 。
#include<bits/stdc++.h>
#define ll long long
#define db double
#define inf 0x3f3f3f3f
using namespace std;
const int N=2e5+5;
const int mod=998244353;
int n,f[N],a[N];
ll dp[N],sum[N];
ll qry(int l,int r) {
if(l>r) return 0;
return (sum[r]-sum[l-1]+mod)%mod;
}
int main() {
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int j=1;
f[1]=sum[1]=dp[1]=1;
for(int i=2;i<=n;i++) {
f[i]=a[i]==a[i-2]?f[i-2]:i;
if(a[i]==a[i-1]) {
j=i;
dp[i]=dp[i-1];
sum[i]=(sum[i-1]+dp[i])%mod;
continue;
}
dp[i]=(qry(j,min(max(f[i],f[i-1])-2,i-3))+qry(max(j,i-2),i-1))%mod;
sum[i]=(sum[i-1]+dp[i])%mod;
}
cout<<dp[n];
}