P6123 [NEERC2016] Hard Refactoring 题解
peixiaorui · · 题解
题意
题目要我们求一个不等式组的解集,并以最简洁的方式输出。我们可以抽象成有多个区间,题目要我们合并区间,若这些区间覆盖了 true ,若这些区间的左端点全部都大于右端点(即 false。
思路
处理出每一个约束条件所代表的区间的左端点和右端点,如果一行只有一个约束条件,那么就将缺少的那个端点设为 x <= 2 转化为左端点为
AC代码
#include<bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define of(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
const int inf=1<<15;
struct node{
int le,ri;
};
bool cmp(node a,node b){return a.le<b.le;}
vector<node> res,ans;
int main(){
int wrong_cnt=0;//记录有多少个左端点大于右端点的区间
while(1){
string xxx,op;int num;
cin>>xxx>>op>>num;
int le=-inf,ri=inf-1;
if(op=="<=")ri=num;
else le=num;//记录第一个端点
if(!(cin>>xxx)){res.push_back({le,ri});break;}
if(xxx=="&&"){
cin>>xxx>>op>>num;
ri=num;//题目保证第二个条件一定是右端点
if(le>ri)wrong_cnt++;
if(!(cin>>xxx)){res.push_back({le,ri});break;}
}
res.push_back({le,ri});//记录区间
}
if(wrong_cnt==res.size()){cout<<"false";return 0;}//如果所有区间都是非法的,输出false
sort(res.begin(),res.end(),cmp);
int le=res[0].le,ri=res[0].ri;
fo(i,1,res.size()-1){
if(res[i].le>res[i].ri)continue;
if(res[i].le>ri+1){
ans.push_back({le,ri});
le=res[i].le,ri=res[i].ri;
continue;
}
ri=max(ri,res[i].ri);
}
ans.push_back({le,ri});//排序并合并区间
if(ans[0].le==-inf&&ans[0].ri==inf-1){cout<<"true";return 0;}//如果区间覆盖了[-32768,32767]输出false
fo(i,0,ans.size()-1){
if(ans[i].ri==inf-1)cout<<"x >= "<<ans[i].le;
else if(ans[i].le==-inf)cout<<"x <= "<<ans[i].ri;
else cout<<"x >= "<<ans[i].le<<" && x <= "<<ans[i].ri;
if(i!=ans.size()-1)cout<<" ||";
cout<<endl;
}//输出
return 0;
}