Codeforces 918C/917A - The Monster
传送门:http://codeforces.com/contest/918/problem/C
一个括弧串由字符‘(’和‘)’组成。一个正确的串可被递归地定义,定义如下:
①空串e是一个正确的串;
②若串s是一个正确的串,则串(s)也是一个正确的串;
③若串s、t均是正确的串,则串st也是一个正确的串。
对于一个由字符‘(’、‘)’和‘?’组成的串s,考虑其子串s.substr(i,j):将这个子串的符号‘?’置换为‘(’或‘)’,若置换后的串是一个正确的串,则原来的子串是一个完美的串。试统计串s中所有的非空完美子串的数目。
这个问题的简单化版本就是括弧匹配,可以通过模拟“栈”以实现:
bool is_correct(const char* ch) { int top = 0; //top of stack for (int i = 0; ch[i] != '\0'; i++) { if (ch[i] == '(') top++; //open parameter else top--; //closed parameter if (top < 0) return false; } if (top == 0) return true; return false; }
接下来,引入符号‘?’,则可以计算top值的上确界sup和下确界inf。将‘?’置换成‘(’,以计算上界;置换成‘)’,以计算下界:
bool is_correct(const char* ch) { int sup = 0, inf = 0; for (int i = 0; ch[i] != '\0'; i++) { if (ch[i] == '(') sup++, inf++; //open parameter else if (ch[i] == ')') sup--, inf--; //closed parameter else sup++, inf--; if (sup < 0) return false; if (inf < 0) inf = 0; } if (strlen(ch) % 2 == 0) if (inf == 0) return true; return false; }
现在考虑本题的问题,则可枚举所有的有序对<i,j>,时间复杂度为O(n2)。参考程序如下:
#include <stdio.h> #define MAX_L 10000 char ch[MAX_L]; int main(void) { scanf("%s", ch); int ans = 0; for (int i = 0; ch[i] != '\0'; i++) { int sup = 0, inf = 0; for (int j = i; ch[j] != '\0'; j++) { if (ch[j] == '(') sup++, inf++; else if (ch[j] == ')') sup--, inf--; else sup++, inf--; if (sup < 0) break; if (inf < 0) inf = 0; if (((j - i) % 2)) if (inf == 0) ans++; } } printf("%d\n", ans); return 0; }
posted on 2018-01-30 20:12 SiuGinHung 阅读(607) 评论(0) 编辑 收藏 举报