#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语言)
原理: 右括号总是与最近的左括号匹配 --- 栈的后进先出 从左往右遍历字符串,遇到左括号就入栈,遇到右括号时,就出栈一个元素与其配对 当栈为空时,遇到右括号,则此右括号无与之匹配的左括号 当最终右括 ...
随机推荐
- 什么是PWA
什么是PWA:https://www.jianshu.com/p/299c9c720e56 2019前端必会黑科技之PWA:https://www.jianshu.com/p/098af61bbe04 ...
- Linux-1.5日志查看常用命令
常访问的日志目录:\data\log\(message系统 | secure安全 | maillog邮件) 进入日志目录 find \d1\data\log -name '*log' 在目录下查找以l ...
- etcd集群安装
etcd 是一个分布式一致性k-v存储系统,可用于服务注册发现与共享配置,具有以下优点:1.简单:相比于晦涩难懂的paxos算法,etcd基于相对简单且易实现的raft算法实现一致性,并通过gRPC提 ...
- luogu P3620 [APIO/CTSC 2007]数据备份
luogu 首先如果一条线不是了连接的相邻两个位置一定不优,把它拆成若干连接相邻位置的线.所以现在问题是有\(n\)个物品,选\(k\)个,要求选的位置不能相邻,求最小总和 如果没有选的位置不能相邻这 ...
- python 一键登录微信分析好友性别 地址 生成结果
# -*- coding:utf- -*- """ author:Mr Yang data:// """ import itchat imp ...
- upupw : Apache Php5.5 的使用
1. 官网下载 1. 官网下载 apache php5.5点击下载 但是 现在有时候打不开,所以提供以下方法 2. 百度云网盘下载 https://pan.baidu.com/s/1eQ2k1Su ...
- centos8 网卡命令(centos7也可用)
nmcli n 查看nmcli状态 nmcli n on 启动nmcli nmcli c up eth0 启动网卡eth0 nmcli c down eth0 关闭网卡eth0 nmcli d c ...
- Mandelbrot集合及其渲染
什么是Mandelbrot集合? Mandelbrot集合是在复数平面上组成分形的点的集合,它正是以数学家Mandelbrot命名. Mandelbrot集合可以用复二次多项式 \[ f_c(z)=z ...
- 生产者消费者问题--synchronized
# 代码 public class App { public static void main(String[] args) { Depot depot = new Depot(100); Produ ...
- hdu2159 二维02bag
设f[i][j]为杀第j只怪时耐久度为i的最大经验值 完全背包类型:有N种物品和一个容量为V 的背包,每种物品都有无限件可用.放入第i种物品的耗费的空间是Ci,得到的价值是Wi. 求解:将哪些物品装入 ...