题目
思路来源
乱搞ac
题解
一个单独的串里的前缀最小值x,前缀和为y
先选x>0 y>0的,选完之后选x<0 y>0的,先选x绝对值小的后大的,
然后选x<0 y<0的,顺序不太显然,但是可以考虑比较法决定哪个在前,
比如,
4
(((
))()))((
)
(3,3)
(-2,-1)
(-3,-1)
(-1,-1)
考虑第二个串和第三个串的顺序时,手玩发现,
当min(a.fi,a.se+b.fi)>min(b.fi,b.se+a.fi),a在前
然后按这个排序一下就过了,其实打开min符号的话,可以发现是良序的,
这个等价于a.se+b.fi>b.se+a.fi,即a.se-a.fi>b.se-b.fi
前缀和-前缀最小值大的在前面
代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
const int N=1e6+10;
vector<P>a,b,c;
int n;
string s[N];
P cal(string &x){
int mn=0,sum=0;
for(auto &v:x){
if(v=='(')sum++;
else sum--;
mn=min(mn,sum);
}
return P(mn,sum);
}
bool sol(){
int tot=0;
rep(i,1,n){
cin>>s[i];
P x=cal(s[i]);
//cout<<"x.fi:"<<x.fi<<" x.se"<<x.se<<endl;
if(x.fi>=0 && x.se>=0)a.pb(x);
else if(x.fi<0 && x.se>=0)b.pb(x);
else c.pb(x);
tot+=x.se;
}
if(tot)return 0;
sort(b.begin(),b.end(),[&](P a,P b){return a.fi>b.fi;});
sort(c.begin(),c.end(),[&](P a,P b){return min(a.fi,a.se+b.fi)>min(b.fi,b.se+a.fi);});
for(auto &x:a)tot+=x.se;
//cout<<"tot:"<<tot<<endl;
for(auto &x:b){
if(x.fi+tot<0)return 0;
tot+=x.se;
}
for(auto &x:c){
if(x.fi+tot<0)return 0;
tot+=x.se;
}
return 1;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
cout<<(sol()?"Yes":"No")<<endl;
return 0;
}
Bonus
2022年WF的签到题H题 同款题目,
顺便可以帮验一下做法耗时,毕竟abc数据比较水
一个极致优化耗时,卡常卡了202ms(c++20)的提交
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;
const int N=1e6+10,M=1e7+10;
char s[M];
struct FastIO{
FILE *fp;
static const int S=1e7+10;
typedef long long ll;
int wpos;
char wbuf[S];
FastIO():wpos(0){}
inline int xchar(){
static char buf[S];
static int len=0,pos=0;
if(pos==len)pos=0,len=fread(buf,1,S,stdin);
return buf[pos++];
}
inline int xuint(){
int c=xchar(),x=0;
while(c<=32)c=xchar();
for(;'0'<=c&&c<='9';c=xchar())x=x*10+c-'0';
return x;
}
inline int xint(){
int s=1,c=xchar(),x=0;
while(c<=32)c=xchar();
if(c=='-')s=-1,c=xchar();
for(;'0'<=c&&c<='9';c=xchar())x=x*10+c-'0';
return x*s;
}
inline void xstring(char *s){
int c=xchar();
while(c<=32)c=xchar();
for(;c>32;c=xchar())*s++=c;
*s=0;
}
inline void wchar(int x){
if(wpos==S)fwrite(wbuf,1,S,stdout);
wbuf[wpos++]=x;
}
inline void wint(int x){
if(x<0)wchar('-'),x=-x;
char s[24];
int n=0;
while(x||!n)s[n++]='0'+x%10,x/=10;
while(n--)wchar(s[n]);
wchar('\n');
}
inline void wstring(const char *s){
while(*s)wchar(*s++);
}
~FastIO(){
if(wpos)fwrite(wbuf,1,wpos,stdout),wpos=0;
}
}io;
bool sol(){
static int n,i,j,tot,tot2,mn,sum;
static int _mn[N],_sum[N],_dif[N],ans[N],id1[N],id2[N],d,e,f;
n=io.xint();
for(i=1;i<=n;++i){
io.xstring(s);
mn=sum=0;
for(j=0;s[j];++j){
if(s[j]=='(')sum++;
else sum--;
if(sum<mn)mn=sum;
}
if(sum>=0){
if(mn>=0)ans[++d]=i,tot2+=sum;
else id1[++e]=i;
}
else id2[++f]=i;
tot+=sum,_mn[i]=mn,_dif[i]=sum-mn,_sum[i]=sum;
}
if(tot)return 0;
sort(id1+1,id1+e+1,[&](int a,int b){return _mn[a]>_mn[b];});
sort(id2+1,id2+f+1,[&](int a,int b){return _dif[a]>_dif[b];});
tot=tot2;
for(i=1;i<=e;++i){
int p=id1[i];
if(_mn[p]+tot<0)return 0;
tot+=_sum[p];
ans[++d]=p;
}
for(i=1;i<=f;++i){
int p=id2[i];
if(_mn[p]+tot<0)return 0;
tot+=_sum[p];
ans[++d]=p;
}
for(i=1;i<=n;++i){
io.wint(ans[i]);
}
return 1;
}
int main(){
if(!sol())puts("impossible");
return 0;
}