1003. Triangle Partition

2018-07-24  本文已影响0人  laochonger

1003. Triangle Partition

题意:给3n个任意三点不在同一直线上的点,找出n个不相交的三角形
标程思路:求个凸包,然后选择凸包一条边 ,然后找个和 夹角最小的点 ,把 当做一个三角形删掉即可。 这样做个n次,显然这样求出来的三角形们是合法的。

但实际上,满足不相交只要按照从左到右,从上到下的顺序删去点即可

标程:(凸包的代码我还没手动敲过 mark)

#include <cstdio>
#include <vector>

using int64 = long long;

struct point {
  int64 x, y;
  int i;
  point(int64 x = 0, int64 y = 0): x(x), y(y) {}
  point operator + (const point& rhs) const {
    return {x + rhs.x, y + rhs.y};
  }
  point operator - (const point& rhs) const {
    return {x - rhs.x, y - rhs.y};
  }
  int64 det(const point& rhs) const {
    return x * rhs.y - y * rhs.x;
  }
  int64 dot(const point& rhs) const {
    return x * rhs.x + y * rhs.y;
  }
};

const int N = 5e3 + 10;

point p[N];

int main() {
  int T;
  scanf("%d", &T);
  for (int cas = 1; cas <= T; ++cas) {
    int n;
    scanf("%d", &n);
    n *= 3;
    for (int i = 0; i < n; ++i) {
      scanf("%lld%lld", &p[i].x, &p[i].y);
      p[i].i = i + 1;
    }
    for (int it = 0; it < n / 3; ++it) {
      int m = n - it * 3;
      int a = 0, b = -1, c = -1;
      // lowest point p_a
      for (int i = 1; i < m; ++i) {
        if (p[i].y < p[a].y || (p[i].y == p[a].y && p[i].x < p[a].x)) a = i;
      }
      // right most point p_b
      for (int i = 0; i < m; ++i) if (i != a) {
        if (b == -1 || (p[b] - p[a]).det(p[i] - p[a]) < 0) b = i;
      }
      // second right most point p_c
      for (int i = 0; i < m; ++i) if (i != a && i != b) {
        if (c == -1 || (p[c] - p[a]).det(p[i] - p[a]) < 0) c = i;
      }
      printf("%d %d %d\n", p[a].i, p[b].i, p[c].i);
      for (int i = 0, j = 0; i < m; ++i) if (i != a && i != b && i != c) {
        p[j++] = p[i];
      }
    }
  }
  return 0;
}

比赛代码:

//B17040312
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

struct point{
    int x;
    int y;
}p[30005];

int pos[30005];

bool cmp(int a , int b){
    if(p[a].x<p[b].x) return true;
    else if(p[a].x>p[b].x) return false;
    else{
        return p[a].y<p[b].y;
    }
}

int main(){
    int t,n;
    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        for(int i = 0; i < 3*n; i++){
            scanf("%d %d", &p[i].x,&p[i].y);
            pos[i] = i;
        }
        sort(pos, pos+3*n, cmp);
        for(int i = 0; i < 3*n; i++){
            printf("%d", pos[i]+1);
            if((i+1)%3==0&&i!=3*n-1) printf("\n");
            else printf(" ");
        }
    }
    return 0;
} 
上一篇 下一篇

猜你喜欢

热点阅读