T1
我第一想到的是dp的状态机模型
设
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k],i为当前扫到第i位,j表示该位的状态,分为三种:0为A,1为N,2为V,k表示是否用过V,1为是,0为否
状态转移见代码。
直接输出
d
p
[
n
]
[
1
]
[
1
]
dp[n][1][1]
dp[n][1][1]即是答案
#include<bits/stdc++.h>
using namespace std;
const int M = 100100;
int a[30], T, len;
char c[M];
int dp[M][3][2];
//状态转移方程
void A(int i){
dp[i+1][0][0] = dp[i][0][0] | dp[i][1][0];
dp[i+1][0][1] = dp[i][0][1] | dp[i][1][1] | dp[i][2][1];
}
void N(int i){
dp[i+1][1][0] = dp[i][1][0] | dp[i][0][0];
dp[i+1][1][1] = dp[i][1][1] | dp[i][0][1] | dp[i][2][1];
}
void V(int i){
if(!i) return;
dp[i+1][2][1] = dp[i][1][0];
}
int main()
{
freopen("language.in", "r", stdin);
freopen("language.out", "w", stdout);
scanf("%d", &T);
while(T--)
{
memset(dp, 0, sizeof dp);
dp[0][0][0] = 1, dp[0][1][0] = 1;
for(int i=0 ; i<26 ; i++)
scanf("%d", &a[i]);
memset(c, 0, sizeof c);
scanf("%s", &c);
for(int i=0 ; c[i] ; i++)
{
int t = c[i]-'a';
if(a[t]==1) A(i);
if(a[t]==2) N(i);
if(a[t]==3) A(i), N(i);
if(a[t]==4) V(i);
if(a[t]==5) A(i), V(i);
if(a[t]==6) N(i), V(i);
if(a[t]==7) A(i), N(i), V(i);
len = i;
}
if(dp[len+1][1][1]) puts("Yes");
else puts("No");
}
return 0;
}
T2
暴力可以拿到前几个点的分,主要讲讲正解。
每个位置用双向链表顺序记录放的球的个数和颜色。对于询问 1,往位置 z 的链表上加一个结点(𝑥, 𝑦)。对于询问 2,从位置 z 的链表头取,如果当前需要取𝒙个而当前结点拥有的球。𝑥′ < 𝑥个,则整个结点删掉,𝑥更新为𝑥 − 𝑥′。如果𝑥′ ≥ 𝑥,那么输出当前的颜色𝑦′,并且把 𝑥′更新为𝑥′ − 𝑥。对于询问 3,把位置𝑢的链表头直接拼接到位置𝑣的链表头上,位置𝑢的链表尾作为位置𝑣新的链表头。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 301001;
struct node {
int c,num,ch[2];
} buf[maxn];
int n,m,h[maxn],t[maxn],tot;
int main() {
scanf("%d%d",&n,&m);
for (int i=0;i<m;i++) {
char op[6];
int x,y,z;
scanf("%s%d%d",op,&x,&y);
if (op[2]=='s') {
scanf("%d",&z);
buf[++tot]=(node){y,x,h[z],0};
if (h[z])
buf[h[z]].ch[0]?(buf[h[z]].ch[1]=tot):(buf[h[z]].ch[0]=tot);
else t[z]=tot;
h[z]=tot;
}
else if (op[2]=='p')
{
while (buf[h[y]].num<x) {
x-=buf[h[y]].num;
int lch=buf[h[y]].ch[0]|buf[h[y]].ch[1];
if (lch)
buf[lch].ch[0]==h[y]?(buf[lch].ch[0]=0):(buf[lch].ch[1]=0);
h[y]=lch;
}
buf[h[y]].num-=x;
printf("%d\n",buf[h[y]].c);
} else {
if (!h[x]) continue;
if (h[y]) {
buf[h[y]].ch[0]?(buf[h[y]].ch[1]=h[x]):(buf[h[y]].ch[0]=h[x]);
buf[h[x]].ch[0]?(buf[h[x]].ch[1]=h[y]):(buf[h[x]].ch[0]=h[y]);
} else
t[y]=h[x];
h[y]=t[x];
h[x]=t[x]=0;
}
}
return 0;
}
T4
我们根据121121进行拓展,发现每次拓展的位数为4、6、10、16,符合斐波拉子数列,所以我们可以用斐波拉子数列优化。
更系统的说法如下,来源:牛客竞赛
由于苯人太菜了,没有写出100的代码,所以我直接搬运了牛客的代码。