0%

P11146 「SFMOI Round I」Strange Train Game

题目大意

给定两个长度为 n 的 01 字符串 a、b,以及 m 次区间操作。每次操作可以选择是否交换区间 [l,r] 内 a 与 b 对应位置的字符。目标是经过若干选择后,使最终得到的 a 的字典序尽可能小,输出最小的结果字符串。

https://class.luogu.com.cn/classroom/LGR197

比赛的时候暴力法打了20分,record:

https://www.luogu.com.cn/record/179510631

前面暴力没搞对是发现是有个双重循环写错了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <bitset>
using namespace std;
const int maxn=2e5+10;
int n,m,l[maxn],r[maxn];
char a[maxn],b[maxn],c[maxn];
// bool vis[maxn];
void out() {
for(int i=1;i<=n;i++) {
cout<<c[i];
}
cout<<endl;
}
inline void compare(){
for(int i=1;i<=n;i++) {
if(c[i]>a[i])
break;
if(a[i]>c[i]) {
for(int j=1;j<=n;j++) {
c[j]=a[j]; // 双重循环一定要小心,前面WA是因为c[i]=a[i]
}
break;
}
}
}
void dfs(int x) {
// out();
// compare();
if(x>m)
return;
for(int i=l[x];i<=r[x];i++) {
swap(a[i],b[i]);
}
compare();
dfs(x+1);
for(int i=l[x];i<=r[x];i++) {
swap(a[i],b[i]);
}
// compare();
dfs(x+1);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) {
cin>>a[i];
}
for(int i=1;i<=n;i++) {
cin>>b[i];
}
for(int _=1;_<=m;_++) {
cin>>l[_]>>r[_];
}
for(int i=1;i<=n;i++)
c[i]=a[i];
dfs(1);
for(int i=1;i<=n;i++) {
cout<<c[i];
}
cout<<endl;
return 0;
}