#4 div1E Parentheses 括号匹配
Time Limit:2000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu
Description
E - Parentheses
Problem Statement
You are given nn strings str1,str2,…,strnstr1,str2,…,strn, each consisting of ( and ). The objective is to determine whether it is possible to permute the nnstrings so that the concatenation of the strings represents a valid string.
Validity of strings are defined as follows:
- The empty string is valid.
- If AA and BB are valid, then the concatenation of AA and BB is valid.
- If AA is valid, then the string obtained by putting AA in a pair of matching parentheses is valid.
- Any other string is not valid.
For example, "()()" and "(())" are valid, while "())" and "((()" are not valid.
Input
The first line of the input contains an integer nn (1≤n≤1001≤n≤100), representing the number of strings. Then nn lines follow, each of which contains stristri (1≤∣stri∣≤1001≤∣stri∣≤100). All characters in stristri are ( or ).
Output
Output a line with "Yes" (without quotes) if you can make a valid string, or "No" otherwise.
Sample Input 1
3
()(()((
))()()(()
)())(())
Output for the Sample Input 1
Yes
Sample Input 2
2
))()((
))((())(
Output for the Sample Input 2
No
题意:每出现一对()时可以消去,现在给你n个由(和)组成的字符串,问能否通过安排这个n个字符串的位置使得
最后没有任何字符留下;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long Ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-10;
const int inf =0x7f7f7f7f;
const double pi=acos(-1);
const int maxn=40000; struct node {
int x,y;
bool operator<(const node&a) const{
return this->x<a.x;
}
};
vector<node> A,B;
char s[10000];
int main()
{
int n;
while(~scanf("%d",&n))
{
A.clear();B.clear();
for(int i=1;i<=n;i++)
{
scanf("%s",s);
int l=0,r=0;
for(int j=0;s[j]!='\0';j++)
{
if(s[j]=='(') r++;
else if(!r) l++;
else r--;
}
if(l>r) B.push_back(node{r,l-r});
else A.push_back((node){l,r-l});
} sort(A.begin(),A.end());
sort(B.begin(),B.end());
int cntA=0,cntB=0; bool flag=true;
for(int i=0;i<A.size();i++)
{
if(A[i].x>cntA) {flag=false;break;}
cntA+=A[i].y;
} for(int i=0;i<B.size();i++)
{
if(B[i].x>cntB) {flag=false;break;}
cntB+=B[i].y;
} if(cntA!=cntB) flag=false;
printf("%s\n",flag?"Yes":"No");
}
return 0;
}
分析:这道题做了很久,其实我的思路大部分是正确的,有几个值得改进的地方:
1.字符串的处理上,我是直接对字符进行移动,而简洁的做法就是直接统计;
我的
while(1)
{
int flag=0;
for(int i=0;s[i+1]!='\0';i++)
{
if(s[i]=='('&&s[i+1]==')')
{
int j;
for(j=i+2;s[j]!='\0';j++)
s[j-2]=s[j];
s[j-2]='\0';
flag=1;
}
if(flag) break;
}
if(!flag) return;
}
简洁:
for(int j=0;s[j]!='\0';j++)
{
if(s[j]=='(') r++;
else if(!r) l++;
else r--;
}
2.最后对右边的处理也不是任意的,比如(((((和右边的)))( ,))))((( , ))左边的与右边的不能任意结合
我的wa代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long Ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-10;
const int inf =0x7f7f7f7f;
const double pi=acos(-1);
const int maxn=40000; char s[100000+10];
int cntl[14],cntr[14],n,l=0,r=0,kk,p,flag[15],used[15]; void init()
{
while(1)
{
int flag=0;
for(int i=0;s[i+1]!='\0';i++)
{
if(s[i]=='('&&s[i+1]==')')
{
int j;
for(j=i+2;s[j]!='\0';j++)
s[j-2]=s[j];
s[j-2]='\0';
flag=1;
}
if(flag) break;
}
if(!flag) return;
}
} struct node{
int id,cntr;
};
bool operator<(node a,node b)
{
return a.cntr<b.cntr;
}
void solve()
{
int l=0;
for(int i=1;i<=n;i++)
if(cntl[i]&&!cntr[i]) {l+=cntl[i];used[i]=1;} if(l==0) {printf("No\n");return;} priority_queue<node> q;
for(int i=1;i<=n;i++)
if(!used[i]&&cntl[i]>=cntr[i])
q.push((node){i,cntr[i]}); while(q.size())
{
node u=q.top();q.pop();
int i=u.id;
if(l<cntr[i]) {printf("No\n");return;}
l+=cntl[i];
l-=cntr[i];
used[i]=1;
} for(int i=1;i<=n;i++)
if(!used[i]&&cntl[i])
{
if(l<cntr[i]) {printf("No\n");return;}
l-=cntr[i];
l+=cntl[i];
used[i]=1;
} for(int i=1;i<=n;i++)
if(!used[i])
{
if(l<cntr[i]) {printf("No\n");return;}
l-=cntr[i];
used[i]=1;
}
if(l) {printf("No\n");return;}
else {printf("Yes\n");return;}
} int main()
{
while(~scanf("%d",&n))
{
MM(cntl,0);MM(cntr,0);MM(used,0);
p=n;l=r=kk=0;
for(int k=1;k<=n;k++)
{
scanf("%s",s);
init();
for(int i=0;s[i]!='\0';i++)
if(s[i]=='(') cntl[k]++;
else if(s[i]==')') cntr[k]++;
if(!cntl[k]&&!cntr[k]) p--;
}
if(p==0) {printf("Yes\n");continue;}
solve();
}
return 0;
}
#4 div1E Parentheses 括号匹配的更多相关文章
- 20. Valid Parentheses(括号匹配,用桟)
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...
- 20. Valid Parentheses - 括号匹配验证
Description: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determin ...
- leetcode 20 Valid Parentheses 括号匹配
Given a string containing just the characters '(', ')', '{', '}', '[' and']', determine if the input ...
- 《LeetBook》leetcode题解(20):Valid Parentheses[E]——栈解决括号匹配问题
我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...
- LeetCode 20 Valid Parentheses (括号匹配问题)
题目链接 https://leetcode.com/problems/valid-parentheses/?tab=Description Problem: 括号匹配问题. 使用栈,先进后出! ...
- 2.Valid Parentheses (括号匹配)
Level: Easy 题目描述: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', ...
- 栈应用之 括号匹配问题(Python 版)
栈应用之 括号匹配问题(Python 版) 检查括号是否闭合 循序扫描被检查正文(一个字符)里的一个个字符 检查中跳过无关字符(所有非括号字符都与当前处理无关) 遇到开括号将其压入栈 遇到闭括号时弹出 ...
- Leetcode 856. Score of Parentheses 括号得分(栈)
Leetcode 856. Score of Parentheses 括号得分(栈) 题目描述 字符串S包含平衡的括号(即左右必定匹配),使用下面的规则计算得分 () 得1分 AB 得A+B的分,比如 ...
- 利用栈实现括号匹配(python语言)
原理: 右括号总是与最近的左括号匹配 --- 栈的后进先出 从左往右遍历字符串,遇到左括号就入栈,遇到右括号时,就出栈一个元素与其配对 当栈为空时,遇到右括号,则此右括号无与之匹配的左括号 当最终右括 ...
随机推荐
- Longest Palindromic Subsequence
Given a string s, find the longest palindromic subsequence's length in s. You may assume that the ma ...
- python控制流 -- if、for、while、range()、sys.exit()
1.布尔值 “布尔”数据类型只有两种:True和False #首字母以T或F开头,后面小写,且不能作为变量赋值 2.比较操作符 == 等于 != 不等于 < 小于 > 大于 &l ...
- Servlet请求和响应
在Java Web中Servlet.请求和响应是最基本的三个对象,在Web容器的管理下,这三者能够完成基本的HTTP请求处理. Servlet的作用是为客户提供服务.servlet的角色是接受一个客户 ...
- Entity Framework常用方法及案例
⒈Skip(int count) 说明:跳过集合的前n个元素:延迟.即我们跳过给定的数目返回后面的结果集. ⒉Take(int count) 说明:获取集合的前n个元素:延迟.即只返回限定数量的结果集 ...
- linux基础命令<二>
1.关机 init 0 poweroff halt shutdown –h now 2.重启 init 6 reboot shutdown –r now 3.查询都有那些用户在系统 ...
- iView 发布后台管理系统 iview-admin
简介 iView Admin 是基于 Vue.js,搭配使用 iView UI 组件库形成的一套后台集成解决方案,由 TalkingData 前端可视化团队部分成员开发维护.iView Admin 遵 ...
- Java 类的构造器中this()和super()的困惑
关于构造器中super的使用,书本上这样写: “super是指向父类的引用,如果构造方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的super()方法调用.如果父类由没有默认的无参 ...
- Python 并发网络库
Python 并发网络库 Tornado VS Gevent VS Asyncio Tornado:并发网络库,同时也是一个 web 微框架 Gevent:绿色线程(greenlet)实现并发,猴子补 ...
- 枚举类型C语言规律用法总结
注:以下全部代码的执行环境为VC++ 6.0 在程序中,可能需要为某些整数定义一个别名,我们可以利用预处理指令#define来完成这项工作,您的代码可能是: #define MON 1#define ...
- 禁止缩放meta标签
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale= ...