一看是个巨水的最小割就来做了。
给出两个字符串由0和1组成,有些位置不知道。把第二个串去匹配第一个串,贡献代价为本次失配字符数。如何决定这些不知道的位置使总代价最小。
可以发现不知道位置只有两种状态:0和1,考虑最小割。
令
xi
表示’?’
那么答案就显而易见了
min{∑max{0,xi−0}⋅(匹配到的0的个数)+∑max{0,1−xi}⋅(匹配到的1的个数)+∑|x−xj|⋅(匹配到?的个数,i和j分别是两个串的)}
输出方案也很简单,
xi
的取值就是方案
#include <cstdio>
#include <cstring>
#include <algorithm>
#define FOR(i,j,k) for(i=j;i<=k;++i)
using namespace std;
const int N = 2555, M = 10000005, inf = 2147483647;
int h[N], p[M], v[M], w[M], edge = 1, s, t;
int level[N], cur[N], vis[N], q[N];
int a0[N], a1[N], id1[N], id2[N], loc[N];
char s1[N], s2[N];
void add(int a, int b, int c) {
p[++edge] = h[a]; v[edge] = b; w[edge] = c; h[a] = edge;
p[++edge] = h[b]; v[edge] = a; w[edge] = 0; h[b] = edge;
}
bool bfs() {
int i, x, f = 0, r = 0;
FOR(i,s,t) level[i] = -1;
q[r++] = s; level[s] = 0;
while (f < r) {
x = q[f++];
for (i = h[x]; i; i = p[i])
if (w[i] && level[v[i]] == -1) {
level[v[i]] = level[x] + 1;
q[r++] = v[i];
}
}
return level[t] != -1;
}
int dfs(int x, int low) {
int i, tmp, res = 0;
if (x == t) return low;
for (i = cur[x]; i && res < low; i = p[i])
if (w[i] && level[v[i]] == level[x] + 1) {
tmp = dfs(v[i], min(low - res, w[i]));
w[i] -= tmp; w[i ^ 1] += tmp; res += tmp;
if (w[i]) cur[x] = i;
}
if (!res) level[x] = -1;
return res;
}
int dinic() {
int ans = 0, i;
while (bfs()) {
FOR(i,s,t) cur[i] = h[i];
ans += dfs(s, inf);
}
return ans;
}
void dfs(int x) {
if (vis[x]) return;
vis[x] = 1;
for (int i = h[x]; i; i = p[i])
if (w[i]) dfs(v[i]);
}
int main() {
int n, m, i, j, k, cnt = 0, ans = 0, e;
scanf("%s%s", s1 + 1, s2 + 1);
n = strlen(s1 + 1); m = strlen(s2 + 1);
FOR(i,1,n) if (s1[i] == '?') id1[i] = ++cnt, loc[cnt] = i; e = cnt;
FOR(i,1,m) if (s2[i] == '?') id2[i] = ++cnt, loc[cnt] = i;
FOR(i,1,n) if (i + m - 1 <= n)
for (j = 1, k = i; j <= m; ++j, ++k) {
if (s1[k] == '0' && s2[j] == '1') ++ans;
if (s1[k] == '1' && s2[j] == '0') ++ans;
if (s1[k] == '?' && s2[j] == '0') ++a0[id1[k]];
if (s1[k] == '?' && s2[j] == '1') ++a1[id1[k]];
if (s1[k] == '0' && s2[j] == '?') ++a0[id2[j]];
if (s1[k] == '1' && s2[j] == '?') ++a1[id2[j]];
if (s1[k] == '?' && s2[j] == '?')
add(id1[k], id2[j], 1), add(id2[j], id1[k], 1);
}
s = 0; t = cnt + 1;
FOR(i,1,n) if (s1[i] == '?')
add(s, id1[i], a0[id1[i]]), add(id1[i], t, a1[id1[i]]);
FOR(i,1,m) if (s2[i] == '?')
add(s, id2[i], a0[id2[i]]), add(id2[i], t, a1[id2[i]]);
printf("%d\n", ans + dinic());
dfs(s);
FOR(i,1,e) s1[loc[i]] = vis[i] ? '0' : '1';
FOR(i,e+1,cnt) s2[loc[i]] = vis[i] ? '0' : '1';
printf("%s\n%s\n", s1 + 1, s2 + 1);
return 0;
}
GOV-internship
Description
Hello Denis,
Your internship in Team.GOV is over. Unfortunately, we cannot make you a full-time offer. Don’t be upset, because you are neither the first nor the last one. It was a great pleasure to work with you. We wish you best of luck.
Regards, Vadim Kantorov, the captain of Team.GOV
A freezing November night in the year of 2010. The dormitory of Department of Mathematics and Mechanics of Ural State University. Dim monitor light. That’s how Den Mukhametianov (the 8th team member in succession) left Team.GOV.
At the beginning of September Den returned from hot summer vacations. He was calmly browsing the photos from a trip when he got an email “You are invited to an interview with Team.GOV”. A year before Den could only dream of this.
The picture emerges in the mind as if it all had been yesterday. It was a small cozy room, Vadik settled comfortably in a rocking chair. Den coughed awkwardly and shitfed his feet. Vadik looked up and smiled. “What experience have you got?”
“Half a year in Ural SU AirBug and half a year in Ural SU Quickov.”
“Hm, not bad. What’s your favorite topic?”
“String algorithms.”
“Well, then straight to the point then,” Vadik interrupted Den. “Let’s pick a problem. Do you know what is Hamming distance between two strings of equal lengths?”
“Yes, it’s the number of positions on which the characters of the strings are not equal.”
“Exactly! Let’s define the distance from a pattern p to a string s as the sum of Hamming distances from p to all substrings of s of length | p|. In the string and in the pattern some characters are erased. You need to recover the erased characters in such a way that the distance from p to s is minimal.”
Input
The first line contains the string s, the second contains the pattern p. Both strings are not empty and their lengths don’t exceed 1000. Strings are comprised of the following characters: “0”, “1” and “?”. Here, “?” stands for erased characters that you need to recover. Length of p doesn’t exceed length of s.
Output
The first line should contain the minimal distance from p to s after all erased characters are recovered. In the second and in the third line output s and p respectively where each character “?” is replaced with either “0” or “1”.
Sample Input
00?
1?
Sample Output
2
000
10