无聊写了一发,莫名1A掉了。不知道题解
dp
怎么个写法 (ˇˍˇ) 想~
hdoj 5903 Square Distance
题意:给定一个偶数长度的字符串
str
,让你构造一个字典序最小的字符串
s
,使得两串中不同字符个数正好为
发现
若
若
str[i]==str[i+n/2]
,那它们的贡献要么是0,要么是2;
思路:考虑对于当前的状态
(i,j)
即第
i
个位置填字符
我们把
[i+1,n/2]
之后的字符分为两类
一、
str[j]!=str[j+n/2]
二、
str[j]==str[j+n/2]
记第一类数目为
num1
,第二类数目为
num2
。
记
x1
为第一类里贡献为1的字符数目,
x2
是贡献为2的字符数目。
记
x3
为第二类里贡献为0的字符数目,
x4
是贡献为2的字符数目。
有方程组
x1+x2=num1
x3+x4=num2
x1+2∗x2+2∗x4=m−(str[i]!=j)−(str[i+n/2]!=j)
把第一个式子代入第三个有
num1+x2+2∗x4=m−(str[i]!=j)−(str[i+n/2]!=j)
x3+x4==num2
我们枚举
x2
的范围
0<=x2<=num1
,看是否存在合法的
x3,x4
使得
0<=x3,x4<=num2
且
x3+x4==num2
。
这样时间复杂度
O(n∗26∗n/2)
。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <cstdlib>
#define ll o<<1
#define rr o<<1|1
#define CLR(a, b) memset(a, (b), sizeof(a))
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 1e3 + 10;
const int INF = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MOD = 1e9 + 7;
char str[MAXN];
int a[MAXN];
int ans[MAXN];
int n, m;
bool judge(int pos, int val) {
int num1 = 0, num2 = 0;
for(int i = pos + 1; i <= n; i++) {
if(a[i] != a[i + n]) { // 1 2
num1++;
}
else { // 0 2
num2++;
}
}
for(int i = 0; i <= num1; i++) {
int x4 = m - val - num1 - i;
if(x4 % 2 == 0) {
x4 /= 2; int x3 = num2 - x4;
if(x3 >= 0 && x3 <= num2 && x4 >= 0 && x4 <= num2) return true;
}
}
return false;
}
int main()
{
int t; scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
scanf("%s", str + 1);
for(int i = 1; i <= n; i++) {
a[i] = str[i] - 'a';
}
n /= 2; bool flag = true;
for(int i = 1; i <= n; i++) {
bool yes = false;
for(int j = 0; j <= 25; j++) {
int cnt = 0;
if(a[i] != j) {
cnt++;
}
if(a[i + n] != j) {
cnt++;
}
if(judge(i, cnt)) {
ans[i] = j;
m -= cnt;
yes = true; break;
}
}
if(!yes) {
flag = false;
break;
}
}
if(!flag) {
printf("Impossible\n");
}
else {
for(int i = 1; i <= n; i++) {
printf("%c", 'a' + ans[i]);
}
for(int i = 1; i <= n; i++) {
printf("%c", 'a' + ans[i]);
}
printf("\n");
}
}
return 0;
}