[ARC190A] Inside or Outside 题解
题目大意
给出一个大小为 \(n\),初始值为 \(0\) 的数组,然后给出 \(m\) 个区间,每个区间选择题目中三种操作中一种,问:当数组最后都为 \(1\) 时,最小代价是多少同时给出方案(可能无解)。
正解
分类讨论。
情况一:有一个区间 \(l=1\) 同时 \(r=n\)。该区间进行操作一,代价为 \(1\)。
情况二:有两个区间不相交。两个区间都选择操作二,代价为 \(2\)。
情况三:有两个区间出现(完全)包含。被包含区间选操作二,另一个选操作一,代价为 \(2\)。
情况四:两个区间可以拼成整个数组。都选操作一,代价为 \(2\)。
情况五:不满足以上且 \(m >2\)。选中间的区间进行操作一,左右进行操作二,代价为 \(3\)。
情况六:以上都不满足。无解。
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+100;
int n,m;
struct Q {
int l,r,id;
} q[MAXN];
bool cmp(Q x,Q y)
{
return x.l<y.l or (x.l==y.l and x.r<y.r);
}
signed main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
q[i].id=i;
scanf("%d %d",&q[i].l,&q[i].r);
if(q[i].l==1 and q[i].r==n)
{
puts("1");
for(int j=1;j<=m;j++)
{
if(i==j)
putchar('1');
else
putchar('0');
putchar(' ');
}
return 0;
}
}
sort(q+1,q+m+1,cmp);
int lst=1,lstt=1;
for(int i=2;i<=m;i++)
{
if(q[lst].r<q[i].l)
{
puts("2");
for(int j=1;j<=m;j++)
{
if(q[i].id==j or q[lst].id==j)
putchar('2');
else
putchar('0');
putchar(' ');
}
return 0;
}
if(q[i].l==q[i-1].l)
{
puts("2");
for(int j=1;j<=m;j++)
{
if(q[i].id==j)
putchar('1');
else if(q[i-1].id==j)
putchar('2');
else
putchar('0');
putchar(' ');
}
return 0;
}
if(q[lstt].r>=q[i].r)
{
puts("2");
for(int j=1;j<=m;j++)
{
if(q[lstt].id==j)
putchar('1');
else if(q[i].id==j)
putchar('2');
else
putchar('0');
putchar(' ');
}
return 0;
}
if(q[lst].r>q[i].r)
lst=i;
if(q[lstt].r<q[i].r)
lstt=i;
}
if(q[1].l==1 and q[m].r==n)
{
puts("2");
for(int i=1;i<=m;i++)
{
if(i==q[1].id or i==q[m].id)
putchar('1');
else
putchar('0');
putchar(' ');
}
return 0;
}
if(m<=2)
{
puts("-1");
return 0;
}
int md=ceil(1.0*m/2);
puts("3");
for(int i=1;i<=m;i++)
{
if(i==q[md].id)
putchar('2');
else if(i==q[md-1].id or i==q[md+1].id)
putchar('1');
else
putchar('0');
putchar(' ');
}
return 0;
}

浙公网安备 33010602011771号