hdu6299 Balanced Sequence
题解:因为是从子序列里面选择括号,所以只要前面有一个左括号‘( ’后面有一个右括号,那就能组成一个合法的括号组合,所以对字符串进行重新排序的时候,要满足让左括号尽量在前面,右括号尽量在后面,而一个字符串自己原串中能组成合法的括号就不用再次判断了。所以我们对每个字符串需要统计的有三个东西,它里面能配成对的对数,落单的左括号数,落单的右括号数。然后对这些字符串进行排序,排序的规则是:题意:给n个字符串,每个字符串是长度不超过1e5的只由' ( '和' ) '组成的串,可以调整不同的串的顺序,但是不能改变一个串自己内部括号的顺序,问最多能组成的合法括号组合的长度。
①. 当左括号多右括号少的字符串c1遇上左括号少的右括号多的字符串c2,c1排在c2前面。(满足左括号尽量在前面,右括号尽量在后面)
②. 当两个字符串都是左括号少右括号多的字符串,按照它们左括号的数量排序。
③其他情况都按照右括号的数量排序。
附上代码:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int l,r,nu;//l左括号,r右括号
bool operator < (const node& aa)const
{
if(l<=r&&aa.l>aa.r)//左少右多 & 左多右少
{
return false;
}
if(l>r&&aa.l<=aa.r)//左多右少 & 左少右多
{
return true;
}
if(r>=l&&aa.r>=aa.l)//左少右多 &7左少右多
{
return l>aa.l;
}
return r<aa.r;//其他情况按右括号的顺序排序
}
}a[100010];
char ss[100010];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",ss);
int len=strlen(ss);
int num1=0,num2=0,num=0;
for(int j=0;j<len;j++)
{
if(ss[j]=='(')
num1++;
else {
if(num1)
num++,num1--;
else
num2++;
}
}
a[i].l=num1;
a[i].r=num2;
a[i].nu=num;
}
sort(a,a+n);
//for(int i=0;i<n;i++)
//printf("%d %d %d\n",a[i].l,a[i].r,a[i].nu);
long long ans=0;
long long pre=0;
for(int i=0;i<n;i++)
{
ans+=a[i].nu;
if(pre&&a[i].r)
{
if(pre>a[i].r)
{
ans+=a[i].r;
pre-=a[i].r;
}
else ans+=pre,pre=0;
}
pre+=a[i].l;
}
printf("%lld\n",ans*2);
}
return 0;
}
hdu 6301 Distinct Values
题意:有一个长度为n的数字序列,给m个要求,每次要求包括一个区间左右端点,要求在给出的这个区间中的数字没有重复的,同时要求数字序列字典序最小,输出这个数字序列。
题解:贪心,对于任何一个位置能填最小的就填最小的,所以对于要求的区间我们按左端点排序,然后从左往右扫过去,对于一个区间没有与其他区间有重合部分的话,就从1开始递增填数,否则,我们用一个优先队列,将有重合区间的非重合部分里填的数放入队列,这部分数就是当前区间没填数的部分可以填的,当队列里的数全部被用完了区间还没完,我们就从上一个区间的最大的数的下一个数开始填,所以需要记录在每个区间里面出现的最大的数,至于判断两区间是否重合可以用一个变量存每个区间的端点就行了。
附上代码:
#include<bits/stdc++.h>
using namespace std;
int ans[100005];
struct node {
int l,r;
bool operator<(const node&aa)const
{
return aa.l>l;
}
}a[100005];
int main() {
int t;
scanf("%d",&t);
while(t--) {
int n,m;
scanf("%d%d",&n,&m);
for(int i=0; i<m; i++)
scanf("%d%d",&a[i].l,&a[i].r);
sort(a,a+m);
for(int i=1; i<=n; i++)
ans[i] = 1;
int l = 0,r = 0;
int maxx = 0;
priority_queue<int,vector<int>,greater<int> >q;
for(int i=0; i<m; i++) {
if(a[i].r<=r)
continue;
if(a[i].l>r)
{
for(int j=a[i].l,k=1; j<=a[i].r; j++,k++)
{
ans[j] = k;
maxx = k;
}
l = a[i].l,r = a[i].r;
while(!q.empty())
q.pop();
}
else {
for(int j=l; j<a[i].l; j++)
q.push(ans[j]);
for(int j=r+1; j<=a[i].r; j++) {
if(!q.empty()) {
ans[j]= q.top();
q.pop();
}
else
{
ans[j] = ++maxx;
}
}
l = a[i].l;
r = a[i].r;
}
}
for(int i=1; i<n; i++) {
printf("%d ",ans[i]);
}
printf("%d\n",ans[n]);
}
return 0;
}