zoukankan      html  css  js  c++  java
  • 【20171111】 Codevs 1214 线段覆盖

    题目描述 Description

        给定x轴上的N(0<N<100)条线段,每个线段由它的二个端点a_I和b_I确定,I=1,2,……N.这些坐标都是区间(-999,999)的整数。有些线段之间会相互交叠或覆盖。请你编写一个程序,从给出的线段中去掉尽量少的线段,使得剩下的线段两两之间没有内部公共点。所谓的内部公共点是指一个点同时属于两条线段且至少在其中一条线段的内部(即除去端点的部分)。

    输入描述 Input Description

        输入第一行是一个整数N。接下来有N行,每行有二个空格隔开的整数,表示一条线段的二个端点的坐标。

    输出描述 Output Description

        输出第一行是一个整数表示最多剩下的线段数。

    样例输入 Sample Input

    3

    6  3

    1  3

    2  5

    样例输出 Sample Output

    2

    数据范围及提示 Data Size & Hint

    0<N<100

    我想,如果把覆盖关系转化为“边”的话,那么输入数据可以转化为一个图,

    题目就变为:删掉最少的点,使得图中剩余点两两不能连通。

    好简单呀,就按照每个点的度降序删点即可!

    但是我的代码速度有待提高……

    数组存图,n^2,

     1 //begin at 16:40
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #define maxn 101
     5 #define _Cover !(ival[i][0]>=ival[j][1]||ival[i][1]<=ival[j][0])
     6 int ival[maxn][3];//interval
     7 //ival[i][2] is the amount of 'i' Coverd intervals
     8 int g[maxn][maxn];//regard the cover
     9 int countCover=0;
    10 int n;
    11 int searchMaxCover()
    12 {
    13     int ans=0,i,maxi;
    14     for(i=0;i<n;i++)
    15     {
    16         if(ival[i][2]>ans)
    17         {
    18             maxi=i;
    19             ans=ival[i][2];
    20         }
    21     }
    22     return maxi;
    23 }
    24 int main()
    25 {
    26     scanf("%d",&n);
    27     int i,j,t;
    28     for(i=0;i<n;i++)
    29     {
    30         scanf("%d%d",&ival[i][0],&ival[i][1]);
    31         if(ival[i][0]>ival[i][1])
    32         {
    33             t=ival[i][0];ival[i][0]=ival[i][1];ival[i][1]=t;
    34         }
    35         ival[i][2]=0;//the amount of Coverd intervals
    36         for(j=0;j<i;j++)
    37         {
    38             if(_Cover)
    39             {
    40                 g[i][j]=g[j][i]=1;//create the edges
    41                 ival[i][2]++;
    42                 ival[j][2]++;
    43                 countCover++;
    44             }
    45             else
    46                 g[i][j]=g[j][i]=0;
    47         }
    48     }
    49     if(countCover==0)
    50     {
    51         printf("%d
    ",n-1-i);
    52         return 0;
    53     }
    54     int p,q;
    55     i=0;
    56     while(countCover>0)
    57     {
    58         i++;
    59         p=searchMaxCover();
    60         for(j=0;j<n;j++)
    61         {
    62             if(g[p][j]==1)
    63             {
    64                 g[p][j]=g[j][p]=0;//delete the edge
    65                 ival[p][2]--;
    66                 ival[j][2]--;
    67                 countCover--;
    68             }
    69         }
    70         if(countCover==0)
    71         {
    72             printf("%d
    ",n-i);
    73             return 0;
    74         }
    75     }
    76     return 0;
    77 }
    78 //end at 17:50
  • 相关阅读:
    【转】关于LWF——线性工作流
    【转】对抗拖库 ―― Web 前端慢加密
    【转】用C#调用Windows API向指定窗口发送
    使用 Redis 如何设计分布式锁?
    SpringBoot如何使用WebSocket实现前后端交互?
    Redis缓存使用中的热key问题
    Spring的BeanUtils的copyProperties方法需要注意的点
    解决github中图片不显示的问题
    java中JsonSerializer的用法(前后端单位转换必备)
    Spring Boot2.X中findOne的用法
  • 原文地址:https://www.cnblogs.com/CXSheng/p/7819607.html
Copyright © 2011-2022 走看看