zoukankan      html  css  js  c++  java
  • poj 1092 Farmland (Geometry)

    1092 -- Farmland

      怎么最近做几何题都这么蛋疼,提交C++过不了交G++就过了。据我估计,原因是用了atan2这个函数,或者是其他一些函数造成了精度的影响。不管怎样,这题最后还是过了~

      解释一下题意,题目的意思是,给出一些边和点,要求找到简单多边形,也就是没有重复的点的多边形,而且多边形里面不能有其他的点。

      于是,还是之前的做法,对于每一条边作为起始边,从这条边出发,找最往左的一个点,然后移动到那里。不停这样的模拟,直到走回起始位置,就计算多边形是由多少条边构成的。如果满足就对计数器加一,最后输出结果即可。

    最早通过的版本的写法是可以不用检查有没有点在多边形里面的:

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cmath>
      6 #include <vector>
      7 #include <map>
      8 
      9 using namespace std;
     10 
     11 const int N = 222;
     12 struct Point {
     13     int x, y;
     14     Point() {}
     15     Point(int x, int y) : x(x), y(y) {}
     16     Point operator + (Point a) { return Point(x + a.x, y + a.y);}
     17     Point operator - (Point a) { return Point(x - a.x, y - a.y);}
     18 } pt[N];
     19 
     20 typedef pair<int, int> PII;
     21 typedef vector<Point> VPT;
     22 typedef vector<int> VI;
     23 
     24 inline double angle(Point x) { return atan2((double) x.y, (double) x.x);}
     25 inline int cross(Point x, Point y) { return x.x * y.y - x.y * y.x;}
     26 
     27 VI rel[N];
     28 Point ori;
     29 map<int, int> pid;
     30 map<int, int> nx[N];
     31 bool vis[N][N], vs[N];
     32 int rec[N];
     33 
     34 inline bool cmp(int a, int b) { return angle(pt[a] - ori) < angle(pt[b] - ori);}
     35 double area() {
     36     double ret = 0.0;
     37     rec[rec[0] + 1] = rec[1];
     38     for (int i = 1; i <= rec[0]; i++) ret += cross(pt[rec[i]], pt[rec[i + 1]]);
     39     return ret / 2.0;
     40 }
     41 
     42 int main() {
     43 //    freopen("in", "r", stdin);
     44 //    freopen("out", "w", stdout);
     45     int T, n, k, x, id;
     46     scanf("%d", &T);
     47     while (T-- && ~scanf("%d", &n)) {
     48         pid.clear();
     49         for (int i = 0; i < n; i++) {
     50             scanf("%d", &id);
     51             if (pid.find(id) == pid.end()) pid[id] = pid.size();
     52             rel[pid[id]].clear();
     53             nx[pid[id]].clear();
     54             scanf("%d%d", &pt[pid[id]].x, &pt[pid[id]].y);
     55             scanf("%d", &k);
     56             while (k--) {
     57                 scanf("%d", &x);
     58                 if (pid.find(x) == pid.end()) pid[x] = pid.size();
     59                 rel[pid[id]].push_back(pid[x]);
     60             }
     61         }
     62 //        for (int i = 1; i <= n; i++) cout << i << ' ' << pid[i] << endl;
     63         scanf("%d", &k);
     64         for (int i = 1, sz; i <= n; i++) {
     65             ori = pt[i];
     66             sort(rel[i].begin(), rel[i].end(), cmp);
     67             sz = rel[i].size();
     68             if (sz <= 1) continue;
     69             rel[i].push_back(rel[i][0]);
     70             for (int j = 0; j < sz; j++) nx[rel[i][j + 1]][i] = rel[i][j];
     71             rel[i].pop_back();
     72         }
     73         memset(vis, 0, sizeof(vis));
     74         int cnt = 0;
     75         for (int i = 1, len, t; i <= n; i++) {
     76             for (int j = 0, sz = rel[i].size(); j < sz; j++) {
     77                 memset(vs, 0, sizeof(vs));
     78                 rec[0] = 0;
     79                 int ls = i, cr = rel[i][j];
     80                 rec[++rec[0]] = ls;
     81                 bool ok = true;
     82                 vs[cr] = true;
     83                 if (vis[ls][cr]) continue;
     84                 len = 1;
     85 //                cout << "start " << i << ' ';
     86                 while (cr != i) {
     87                     rec[++rec[0]] = cr;
     88 //                    cout << cr << ' ';
     89                     t = cr;
     90                     cr = nx[ls][cr];
     91                     if (cr <= 0) {
     92                         len = -1;
     93                         break;
     94                     }
     95                     if (vs[cr]) ok = false;
     96                     vs[cr] = true;
     97                     ls = t;
     98                     vis[ls][cr] = true;
     99                     len++;
    100                 }
    101 //                cout << "~~" << len << endl;
    102                 if (ok && len == k && vs[nx[ls][cr]] && area() > 0.0) cnt++;
    103             }
    104         }
    105         printf("%d
    ", cnt);
    106     }
    107     return 0;
    108 }
    View Code

      因为开始的时候wa太多次了,所以我的代码对标号重标号了。

    然后不停的改啊改,最后改到把检查点在多边形内的操作也加上去了~

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cmath>
      6 #include <vector>
      7 #include <map>
      8 
      9 using namespace std;
     10 
     11 const int N = 222;
     12 struct Point {
     13     int x, y;
     14     Point() {}
     15     Point(int x, int y) : x(x), y(y) {}
     16     Point operator + (Point a) { return Point(x + a.x, y + a.y);}
     17     Point operator - (Point a) { return Point(x - a.x, y - a.y);}
     18 } pt[N];
     19 
     20 typedef pair<int, int> PII;
     21 typedef vector<Point> VPT;
     22 typedef vector<int> VI;
     23 
     24 inline double angle(Point x) { return atan2((double) x.y, (double) x.x);}
     25 inline int cross(Point x, Point y) { return x.x * y.y - x.y * y.x;}
     26 
     27 VI rel[N];
     28 Point ori;
     29 map<int, int> pid;
     30 map<int, int> nx[N];
     31 bool vis[N][N], vs[N];
     32 int rec[N];
     33 
     34 inline bool cmp(int a, int b) { return angle(pt[a] - ori) < angle(pt[b] - ori);}
     35 double area() {
     36     double ret = 0.0;
     37     rec[rec[0] + 1] = rec[1];
     38     for (int i = 1; i <= rec[0]; i++) ret += cross(pt[rec[i]], pt[rec[i + 1]]);
     39     return ret / 2.0;
     40 }
     41 
     42 bool test(int p) {
     43     int sz = rec[0], wn = 0;
     44     rec[sz + 1] = rec[1];
     45     for (int i = 1; i <= sz; i++) {
     46         if (pt[p].x == pt[rec[i]].x && pt[p].y == pt[rec[i]].y) return false;
     47         int k = cross(pt[rec[i + 1]] - pt[rec[i]], pt[p] - pt[rec[i]]);
     48         int d1 = pt[rec[i]].y - pt[p].y;
     49         int d2 = pt[rec[i + 1]].y - pt[p].y;
     50         if (k > 0 && d1 <= 0 && d2 > 0) wn++;
     51         if (k < 0 && d2 <= 0 && d1 > 0) wn--;
     52     }
     53     return wn != 0;
     54 }
     55 
     56 bool check() {
     57 //    for (int i = 1; i <= rec[0]; i++) cout << rec[i] << ' '; cout << endl;
     58     for (int i = 1, sz = pid.size(); i <= sz; i++) {
     59         if (test(i)) return false;
     60     }
     61     return true;
     62 }
     63 
     64 int main() {
     65 //    freopen("in", "r", stdin);
     66 //    freopen("out", "w", stdout);
     67     int T, n, k, x, id;
     68     scanf("%d", &T);
     69     while (T-- && ~scanf("%d", &n)) {
     70         pid.clear();
     71         for (int i = 0; i < n; i++) {
     72             scanf("%d", &id);
     73             if (pid.find(id) == pid.end()) pid[id] = pid.size();
     74             rel[pid[id]].clear();
     75             nx[pid[id]].clear();
     76             scanf("%d%d", &pt[pid[id]].x, &pt[pid[id]].y);
     77             scanf("%d", &k);
     78             while (k--) {
     79                 scanf("%d", &x);
     80                 if (pid.find(x) == pid.end()) pid[x] = pid.size();
     81                 rel[pid[id]].push_back(pid[x]);
     82             }
     83         }
     84 //        for (int i = 1; i <= n; i++) cout << i << ' ' << pid[i] << endl;
     85         scanf("%d", &k);
     86         if (k < 3) { puts("0"); continue;}
     87         for (int i = 1, sz; i <= n; i++) {
     88             ori = pt[i];
     89             sort(rel[i].begin(), rel[i].end(), cmp);
     90             sz = rel[i].size();
     91             if (sz <= 1) continue;
     92             rel[i].push_back(rel[i][0]);
     93             for (int j = 0; j < sz; j++) nx[rel[i][j + 1]][i] = rel[i][j];
     94             rel[i].pop_back();
     95         }
     96         memset(vis, 0, sizeof(vis));
     97         int cnt = 0;
     98         for (int i = 1, len, t; i <= n; i++) {
     99             for (int j = 0, sz = rel[i].size(); j < sz; j++) {
    100                 rec[0] = 0;
    101                 int ls = i, cr = rel[i][j];
    102                 if (vis[ls][cr]) continue;
    103                 vis[ls][cr] = true;
    104                 bool ok = true;
    105                 memset(vs, 0, sizeof(vs));
    106                 len = 1;
    107 //                cout << "start " << i << ' ';
    108                 while (nx[ls][cr]) {
    109                     rec[++rec[0]] = cr;
    110 //                    cout << cr << ' ';
    111                     t = cr;
    112                     cr = nx[ls][cr];
    113                     if (cr <= 0) {
    114                         len = -1;
    115                         break;
    116                     }
    117                     if (vs[cr]) ok = false;
    118                     vs[cr] = true;
    119                     ls = t;
    120                     if (vis[ls][cr]) break;
    121                     vis[ls][cr] = true;
    122                     len++;
    123                 }
    124 //                cout << "~~" << len << endl;
    125                 if (ok && len == k && ls == i && area() >= 1e-5 && check()) cnt++;
    126             }
    127         }
    128         printf("%d
    ", cnt);
    129     }
    130     return 0;
    131 }
    View Code

    ——written by Lyon

  • 相关阅读:
    struts2 easyui实现datagrid的crud
    Codeforces 10A-Power Consumption Calculation(模拟)
    Java5新特性之枚举
    [总结]视音频编解码技术零基础学习方法
    (三 )kafka-jstorm集群实时日志分析 之 ---------jstorm集成spring 续(代码)
    codeforces Looksery Cup 2015 H Degenerate Matrix 二分 注意浮点数陷阱
    NHibernate3剖析:Query篇之NHibernate.Linq增强查询
    hdoj 1013Digital Roots
    小Y的难题
    【前端JS】radio 可单选可点击取消选中
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_1092_Lyon.html
Copyright © 2011-2022 走看看