重复最长的两个线段

题目:


分析:

思路:先排序,后贪心

设输入线段的数组为A[0..n-1],每条线段为(x, y)

(1)首先将A排序(先按x排,如果x相等,则按y排)

(2)令opt(i) 表示a[i]与a[j]相交的最大长度(其中i < j < n)

          令a[k]表示a[i+1], a[i+2], a[i+3], .., a[n-1]中第一条不完全被a[i]覆盖的线段 (a[k].y >= a[i].y) 

          那么,必有       
          (a) opt[i] = max(intersection_len(a[i], a[j])), 其中i<j<=k
          (b)对任意 i<p<k, opt[p] <= opt[i] 
(3)要求的值为max(opt[i]), 0 =< i < n


#include<stdio.h>
typedef struct _line
{
  int x;
  int y;
}Line;
int cmp(const void* a, const void* b)
{
  Line* l1 = (Line*)a;
  Line* l2 = (Line*)b;
  if(l1->x != l2->x) return l1->x - l2->x;
  return l1->y - l2->y;
}
int inter_sect(const Line* a, const Line* b)
{
  int x = a->x;
  if(b->x > x) x = b->x;
  int y = a->y;
  if(b->y < y) y = b->y;
  return y - x;
}
int main()
{
  int n;
  Line a[10000];
  scanf("%d", &n);
  int i, j;
  for(i = 0; i < n; i++) scanf("%d %d", &a[i].x, &a[i].y);
  qsort(a, n, sizeof(a[0]), cmp);
  int mark1, mark2, max = -1;
  for(i = 0; i < n; )
  {
    int local_max = 0, local_index;
    for(j = i + 1; j < n; j++)
    {
      int t = inter_sect(a + i, a + j);
      if(t > local_max)
      {
        local_max = t;
        local_index = j;
      }
      if(a[j].y >= a[i].y) break;
    }
    if(local_max > max)
    {
      max = local_max;
      mark1 = i;
      mark2 = local_index;
    }
    i = j;
  }
  printf("max intersction: (%d, %d), (%d, %d)\n", a[mark1].x, a[mark1].y, a[mark2].x, a[mark2].y);
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值