#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语言)
原理: 右括号总是与最近的左括号匹配 --- 栈的后进先出 从左往右遍历字符串,遇到左括号就入栈,遇到右括号时,就出栈一个元素与其配对 当栈为空时,遇到右括号,则此右括号无与之匹配的左括号 当最终右括 ...
随机推荐
- 【0.1】mysql版本升级(5.6升级到5.7)
目录 [1].升级操作 [2].mysql 5.6安装(二进制) [3].mysql 5.7安装(二进制) [1].升级操作 核心步骤 [1.1]停止mysql 5.6 [1.2]把环境变量引用到My ...
- 小菜鸟之Oracle数据库
select * from STUDENT; select * from mark; select * from COURSE; select * from teacher; --注释 select ...
- tourist's modular arithmetic class
#include <bits/stdc++.h> using namespace std; template <typename T> T inverse(T a, T m) ...
- 【模板】SPFA(不完全详解)
一种最短路求法(个人觉得比DIJKSTRA好用) 用于有向图. 大概思路:从根节点开始,枚举每一个点,同时更新他们所联通的点的最短路径,如果路径被更新,则把这个点入队,一直重复这个操作直到队伍为空为止 ...
- 基于Keras的OpenAI-gym强化学习的车杆/FlappyBird游戏
强化学习 课程:Q-Learning强化学习(李宏毅).深度强化学习 强化学习是一种允许你创造能从环境中交互学习的AI Agent的机器学习算法,其通过试错来学习.如上图所示,大脑代表AI Agent ...
- 算法分析方法之平摊分析(Amotized Analysis)
- docker之常用命令
1) docker run -p : --name mysql -v d:/docker/mysql/conf:/etc/mysql/conf.d -v d:/docker/mysql/logs:/l ...
- 入门&常量&变量
位:二进制中,每个0或1就是一个位,叫做bit(比特) 字节:计算机最小是存储单元(byte或B) 8bit = 1B 常用cmd命令: 启动: Win+R,输入cmd回车切换盘符 盘符名称:进入文件 ...
- 查看Linux服务器硬件信息
一:查看cpu# 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数# 查看物理CPU个数cat /proc/cpui ...
- python 写入JSON中文乱码解决方法
在将一个字典添加入json中时多加入一个参数就可以了 json.dumps(dict(item), ensure_ascii=False) 例子 with open('zh-cn.json','w', ...