重复最长的两个线段

来源:互联网 发布:学好高中数学的软件 编辑:程序博客网 时间:2024/05/18 01:58

题目:


分析:

思路:先排序,后贪心

设输入线段的数组为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;}