题目:​​http://codeforces.com/problemset/problem/3/D​

( ??)

( ( ))

(()))……


这个问题基于贪心思路解决,给定的字符串如果是可行的,那么左边多出的一定是(,右边如果有多出的那一定是)。那么对于出现的?直接选填),这样不断抵消,如果多了),那就把之前的某个)换成(,注意换后cost就会-b+a,要让cost小就要a-b小,也即是要换取b-a最大的?成(,用过的?就不再用,即出队列了。这样保证了这一阶段状态是最小的,那么下一状态,下下一状态同样是最小的(贪心成立)。设置一个计数器计算左括号的个数,由于抵消,该数会不断变小,也可能局部变大。选填所有的?后,如果计数器是0则成功匹配完全,否则输出-1.(又学到了好东西,puts("-1");直接换到下一行了。)最后,让我来吐槽一下CF,太慢了(也有可能是我网的原因)!还有:

    //while(cin>>s){  (1)

    cin>>s;           (2)

要用第2种方式读入字符串,不能用第一种,反正我用第一种就一直死在51th test上(难道平台是用很多个文件来测试的?


要用第2种方式读入字符串,不能用第一种(难道平台是用很多个文件来测试的?*^_^*)
还发现了一个怪现象:

#include<queue>
#include<iostream>
using namespace std;
struct point {
int x,y;
};
/*struct cmp{
bool operator()(const point a,const point b)const {
return (a.x+a.y)<(b.x+b.y);
}
};*/
bool operator<(const point a,const point b){
return (a.x+a.y)<(b.x+b.y);
}
void show(point a){
cout<<a.x<<','<<a.y<<endl;
}
int main(){ //优先队列按照从大到小的顺序排列输出
//priority_queue<point,vector<point>,cmp> v; 两种方式均可以的
priority_queue<point> v;
point p[2]={{2,9},{4,3}};
for( int i = 0; i < 2; i++ ) {
v.push(p[i]);
}
while( !v.empty() ) {
show(v.top());
v.pop();
}
cout<<"v.size: "<<v.size()<<endl;
cout<<"after all deleted:\n";
point tmp=v.top();
v.pop();
show(tmp);
tmp=v.top();
v.pop();
show(tmp);
return 0;
}

输出结果:


2,9

4,3

v.size: 0

after all deleted:

4,3

2113747224,134280876


明明都已经empty了,为什么还能输出4,3呢?看来要好好学学C++了。。。


这个问题的解决代码(还可以再修改):

#include <iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=5e5+5;
char s[maxn];
struct node{
long long pay,id;
bool operator <(const node &b)const {
return pay<b.pay;
}
};
int main()
{
cin>>s;
priority_queue<node> que;
long long i,a,b,length=strlen(s),sum=0,cost=0;
for(i=0;i<length;i++){
if(s[i]=='(')sum++;
else if(s[i]==')')sum--;
else {
scanf("%I64d%I64d",&a,&b);
node tmp;
tmp.pay=b-a;
tmp.id=i;
que.push(tmp);
s[i]=')';
cost+=b;
sum--;
}
if(sum<0){
if(que.empty())break;
node tmp;
tmp=que.top();
que.pop();
sum+=2;
cost-=tmp.pay;
s[tmp.id]='(';
}
}
if(sum==0)printf("%I64d\n%s\n",cost,s);
else printf("-1\n");
while(!que.empty())que.pop();
return 0;
}