C - Canvas Line Kattis - canvasline(细节题)

Your friend Charmion asked you to hang some canvases out to dry on a straight washing line for an art project she has been working on. The canvases are artfully arranged such that none of them overlap, although they may touch along the edges. For stability, each canvas must be held by two pegs, but because the canvases are very rigid, they can be held from anywhere.

Each canvas is an integral number of centimetres wide (at least [Math Processing Error] cm). Each peg is slightly less than [Math Processing Error] cm wide. Canvases and pegs are all placed at integral centimetre positions along the line.

Unnecessary things touching any canvas is a smudge risk, thus every canvas should be held by exactly two pegs, no more and no less. Given all of the pegs that are already attached to the line, place as few as possible additional pegs as necessary to hold all of the canvases.
Figure 1: Illustration of a solution to Sample Input 2. Pre-existing pegs are marked in white.
Input
The input consists of:

One line with an integer [Math Processing Error] ([Math Processing Error]), the number of canvases on the line.

[Math Processing Error] lines, the [Math Processing Error]th of which contains two integers [Math Processing Error] and [Math Processing Error] ([Math Processing Error] and [Math Processing Error]), the positions of the left and the right end of the [Math Processing Error]th canvas in centimetres.

One line with an integer [Math Processing Error] ([Math Processing Error]), the number of pegs already used.

One line with [Math Processing Error] integers [Math Processing Error] ([Math Processing Error] for each [Math Processing Error]), the position of each existing peg in centimetres.

Canvases are given from left to right and may touch only at edges, that is [Math Processing Error] for each [Math Processing Error].

Output
If the canvases can be secured, output the smallest number of extra pegs needed to secure all of the canvases while touching each exactly twice. On the next line output the integer positions of all of the new pegs.

Otherwise, output “impossible”.

If there are multiple optimal solutions, you may output any one of them.
在这里插入图片描述
细节题:
代码

#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <deque>
#include <list>
#include <map>
#include <iostream>
#include <istream>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define Max 1000001
struct node
{
    int l,r;
    int lock;
} a[1001];
map<int,int>vis;
int main()
{
    int n;
    cin>>n;

    for(int i=0; i<n; i++)
    {
        cin>>a[i].l>>a[i].r;
        a[i].lock=0;
    }
    int p;
    cin>>p;
    for(int i=0; i<p; i++)
    {
        int key;
        cin>>key;
        vis[key]=1;
        int l=0,r=n-1;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(a[mid].l>key)
            {
                r=mid-1;
            }
            else if(a[mid].l<=key&&a[mid].r>=key)
            {
                a[mid].lock++;
                if(a[mid].l==key)
                {
                    if(mid>0&&a[mid-1].r==key)
                    {
                        a[mid-1].lock++;
                    }
                }
                else if(a[mid].r==key)
                {
                    if(mid<n-1&&a[mid+1].l==key)
                    {
                        a[mid+1].lock++;
                    }
                }
                break;
            }
            else  if(a[mid].r<key)
            {
                l=mid+1;
            }
        }
    }
    int flag=0;
    int b[2001];
    int cnt=0;
    for(int i=0; i<n; i++)
    {
        if(a[i].lock>2)
        {
            flag=1;
            break;
        }
        else if(a[i].lock==2)
        {
            continue;
        }
        else
        {
            if(a[i].lock==0)//1个钩子都没有
            {
                b[cnt++]=a[i].l+1;//一定不能和前面共用钩子
                a[i].lock++;
                //看能不能跟后面共用钩子
                if(i<n-1)//后面还有画布
                {
                    if(a[i].r==a[i+1].l)
                    {
                        if(a[i+1].lock==2)//后面已经有两个钩子
                        {
                            b[cnt++]=a[i].r-1;
                            vis[a[i].r-1]=1;
                            a[i].lock++;
                        }
                        else
                        {
                            b[cnt++]=a[i].r;
                            vis[a[i].r]=1;
                            a[i].lock++;
                            a[i+1].lock++;
                        }
                    }
                    else
                    {
                        vis[a[i].r]=1;
                        a[i].lock++;
                        b[cnt++]=a[i].r;
                    }
                }
                else
                {
                    b[cnt++]=a[i].r;
                    vis[a[i].r]=1;
                    a[i].lock++;
                }
            }
            else//有一个钩子
            {
                if(vis[a[i].l]==1)//钩子在左边,和前一个公用
                {
                    if(i<n-1)
                    {
                        if(a[i].r==a[i+1].l)
                        {
                            if(a[i+1].lock==2)//不能挂在公共处
                            {
                                b[cnt++]=a[i].r-1;
                                vis[a[i].r-1]=1;
                                a[i].lock++;
                            }
                            else
                            {
                                b[cnt++]=a[i].r;
                                vis[a[i].r]=1;
                                a[i].lock++;
                                a[i+1].lock++;
                            }
                        }
                        else//两个画布不相接
                        {
                            b[cnt++]=a[i].r;
                            vis[a[i].r]=1;
                            a[i].lock++;
                        }
                    }
                    else//最后一个画布
                    {
                        b[cnt++]=a[i].r;
                        vis[a[i].r]=1;
                        a[i].lock++;
                    }
                }
                else if(vis[a[i].r]==1)//钩子在右边,和后一个共用
                {
                    b[cnt++]=a[i].l+1;
                    vis[a[i].l+1]=1;
                    a[i].lock++;
                }
                else//在中间
                {
                    if(i<n-1)
                    {
                        if(a[i].r==a[i+1].l)
                        {
                            if(a[i+1].lock==2)//不能挂在公共处
                            {
                                for(int k=a[i].l+1;k<=a[i].r-1;k++)
                                {
                                    if(!vis[k])
                                    {
                                        b[cnt++]=k;
                                        vis[k]=1;
                                        a[i].lock++;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                b[cnt++]=a[i].r;
                                vis[a[i].r]=1;
                                a[i].lock++;
                                a[i+1].lock++;
                            }
                        }
                        else//两个画布不相接
                        {
                            b[cnt++]=a[i].r;
                            vis[a[i].r]=1;
                            a[i].lock++;
                        }
                    }
                    else//最后一个画布
                    {
                        b[cnt++]=a[i].r;
                        vis[a[i].r]=1;
                        a[i].lock++;
                    }
                }
            }
            if(a[i].lock==2)
            {
                continue;
            }
            else
            {
                flag=1;
                break;
            }
        }
    }

    if(flag)
    {
        cout<<"impossible"<<endl;
    }
    else
    {
        cout<<cnt<<endl;
        for(int i=0; i<cnt; i++)
        {
            if(i<cnt-1)
            {
                cout<<b[i]<<" ";
            }
            else
            {
                cout<<b[i]<<endl;
            }
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值