题目链接;
POJ 1142 Brackets Sequence
题意:
给一个只含
"(",")","[","]"
四种括号的字符串,这个串可能不是恰好匹配的,输出最短的完美匹配串,多解输出任意解。
数据范围:
长度≤100
例如:对于
([(]
应输出
()[()]
分析:
坑爹啊,输入会有空行,然后需要输出空行,所以不能用scanf()
这道题是POJ 2955 Brackets的加深。
设字符串长度为
n
,下标从0开始,求出
int total = 0;
for (int i = 0; i < n; ++i) {
if (dp[i][n - 1] == 0) {
while(i < n) {
ans[total++] = s[i++];
}
ans[total++] = '\0';
// printf("case1 i = %d\n", i);
break;
}
if(i == n - 1) {
if(s[i] == '[' || s[i] == ']') {
ans[total++] = '[';
ans[total++] = ']';
} else {
ans[total++] = '(';
ans[total++] = ')';
}
ans[total++] = '\0';
// printf("case2 i = %d\n", i);
break;
} else {
if(dp[i][n - 1] > dp[i + 1][n - 1]) {
//printf("case3 i = %d\n", i);
if (s[i] == ')' || s[i] == '(') {
ans[total++] = '(';
ans[total++] = ')';
} else if (s[i] == ']' || s[i] == '[') {
ans[total++] = '[';
ans[total++] = ']';
}
} else {
//printf("case4 i = %d\n", i);
ans[total++] = s[i];
int num = 1;
char goal, ori = s[i];
if(s[i] == '[') goal = ']';
else goal = ')';
++i;
while(num) {
if (s[i] == goal) {
ans[total++] = s[i];
num--;
} else if (s[i] == ori) {
ans[total++] = s[i];
num++;
} else if (s[i] == '[' || s[i] == ']') {
ans[total++] = '[';
ans[total++] = ']';
} else {
ans[total++] = '(';
ans[total++] = ')';
}
++i;
}
--i;
}
}
}
puts(ans);
很长很low,而且交上去还wa了。。。想出来一种反例:[(()],而且发现这种反例我完全不会处理。。。。
这就很尴尬了。。。。
后来经小伙伴提醒发现可以在处理
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
const int MAX_N = 110;
const int inf = 0x3f3f3f3f;
char s[MAX_N];
int dp[MAX_N][MAX_N], pre[MAX_N][MAX_N];
void dfs(int left, int right)
{
if(left > right) return;
if(left == right) {
if(s[left] == '(' || s[left] == ')') {
printf("()");
} else {
printf("[]");
}
return ;
}
if(pre[left][right] == -1) {
printf("%c", s[left]);
dfs(left + 1, right - 1);
printf("%c", s[right]);
} else {
dfs(left, pre[left][right]);
dfs(pre[left][right] + 1, right);
}
}
int main()
{
while (gets(s)) {
int n = strlen(s);
if(n == 0) {
printf("\n");
continue;
}
for(int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i > j) dp[i][j] = 0;
else if(i == j) dp[i][j] = 1;
else dp[i][j] = inf;
}
}
for (int i = n - 1; i >= 0; --i) {
for (int j = i; j < n; ++j) {
if((s[i] == '(' && s[j] == ')') ||
s[i] == '[' && s[j] == ']') {
dp[i][j] = dp[i + 1][j - 1];
pre[i][j] = -1;
}
for (int k = i; k < j; ++k) {
if (dp[i][k] + dp[k + 1][j] < dp[i][j]) {
dp[i][j] = dp[i][k] + dp[k + 1][j];
pre[i][j] = k;
}
}
}
}
dfs(0, n - 1);
printf("\n");
}
return 0;
}