前言
时间就是金钱 就是生命 ,所以直接从D题开始补了
传送门:
D.Swap Hats
题目很简单,但是有一个 分析状态 的思想值得学习
我们简单分为
- (1)有三个不同
- (2)有两个不同
- (3)都相同
显然 状态(1)(3) 无论如何怎么操作都只能 转换到 状态(2)
但是状态(2) 一次操作 只能转换到 (1)(3)
因此在 1 e 18 1e^{18} 1e18的偶数操作下,只有(1)(3)状态是合法的
Mycode
void solve()
{
char a,b,c;cin>>a>>b>>c;
char A,B,C;cin>>A>>B>>C;
int t = (A == a) + (B == b) + (C == c);
if(!t || t== 3){
cout<<"Yes"<<endl;
return;
}
cout<<"No"<<endl;
}
E - King Bombee
一个 N ∗ M N*M N∗M的无向图
给你 S , T , K , X S,T,K,X S,T,K,X 询问有多少条长度为 K + 1 K+1 K+1的 V s t o V t V_s \ to\ V_t Vs to Vt 路径满足 X X X出现了偶数次
我们设计状态为
f
[
i
]
[
j
]
[
k
]
f[i][j][k]
f[i][j][k]表示前面有
i
i
i个字母,末尾是
j
j
j,并且出现
k
k
k次
X
X
X的状态
初始化 f [ 1 ] [ S ] [ 0 ] = 1 f[1][S][0] = 1 f[1][S][0]=1 最终状态 f [ k + 1 ] [ T ] [ 0 ] f[k+1][T][0] f[k+1][T][0]
因此我们只需要遍历 次数的时候 遍历一下所有边即可
在每次 f [ i − 1 ] [ j ] [ 1 ] ∣ ∣ f [ i − 1 ] [ j ] [ 0 ] f[i-1][j][1] ||f[i-1][j][0] f[i−1][j][1]∣∣f[i−1][j][0] 状态存在的时候做转移即可
Mycode
ll f[N][N][2];
vector<int> g[N];
int n,m,k,S,T,x;
void solve()
{
cin>>n>>m>>k>>S>>T>>x;
while(m -- ){
int a,b;cin>>a>>b;
g[a].pb(b);g[b].pb(a);
}
f[1][S][0] = 1;
//长度是 k+1
for(int i=2;i<=k+1;i ++ ){
for(int j = 1;j<=n;j++ ){
if(f[i-1][j][0] || f[i-1][j][1]){
for(auto e : g[j]){
if(e == x){
f[i][e][1] = (f[i][e][1] + f[i-1][j][0])%mod;
f[i][e][0] = (f[i][e][0] + f[i-1][j][1])%mod;
}else{
f[i][e][0] = (f[i][e][0] + f[i-1][j][0])%mod;
f[i][e][1] = (f[i][e][1] + f[i-1][j][1])%mod;
}
}
}
}
}
cout<<f[k+1][T][0]<<endl;
}