hdu 4305 Lightning

http://acm.hdu.edu.cn/statistic.php?pid=4305&from=126&lang=&order_type=0

  生成树计数加上极角排序,开始的时候忘记了计算过程中,数值会变成负数,所以wa了一次。生成树计数的矩阵运算必须注意,最后答案应该将它调整为整数。

  题意是有n(n<=300)个人,如果某个人被电了,在他附近r范围内的人都会被电,算出被电的人形成的图案的种类数。两个能传递的人之间的直线位置不能有第三个人。

1800+ms的代码。。。囧:

View Code
  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <cmath>
  5 
  6 using namespace std;
  7 
  8 const int maxn = 305;
  9 const int maxSize = 305;
 10 const int initMod = 10007;
 11 const double eps = 1e-12;
 12 int curSize = maxSize;
 13 
 14 struct point {
 15     int x;
 16     int y;
 17     int id;
 18 
 19     bool operator == (point &a) const {
 20         return x == a.x && y == a.y;
 21     }
 22 } pt[maxn], p0, buf[maxn];
 23 
 24 int dis2(point &a, point &b) {
 25     int dx = a.x - b.x;
 26     int dy = a.y - b.y;
 27 
 28     return dx * dx + dy * dy;
 29 }
 30 
 31 bool cmp(point a, point b) {
 32     if (a == p0) return true;
 33     if (b == p0) return false;
 34 
 35     double tmp = atan2(a.y - p0.y, a.x - p0.x) - atan2(b.y - p0.y, b.x - p0.x);
 36 
 37     if (fabs(tmp) < eps) return dis2(a, p0) < dis2(b, p0);
 38     return tmp < 0;
 39 }
 40 
 41 struct Mat {
 42     int val[maxSize][maxSize];
 43 
 44     Mat () {
 45         for (int i = 0; i < curSize; i++) {
 46             for (int j = 0; j < curSize; j++) {
 47                 val[i][j] = 0;
 48             }
 49         }
 50     }
 51     int det() {
 52         int ret = 1;
 53 
 54         for (int p = 1; p < curSize; p++) {
 55             for (int i = p + 1; i < curSize; i++) {
 56                 while (val[i][p]) {
 57                     int k = val[p][p] / val[i][p];
 58 
 59                     for (int j = p; j < curSize; j++) {
 60                         val[p][j] = (val[p][j] - val[i][j] * (k % initMod)) % initMod;
 61                         swap(val[p][j], val[i][j]);
 62                     }
 63                     ret = -ret;
 64                 }
 65             }
 66             ret *= val[p][p];
 67             ret = (ret % initMod + initMod) % initMod;
 68         }
 69 
 70         return ret;
 71     }
 72     void print() {
 73         for (int i = 0; i < curSize; i++) {
 74             for (int j = 0; j < curSize; j++) {
 75                 printf("%d ", val[i][j]);
 76             }
 77             puts("");
 78         }
 79         puts("~~~");
 80     }
 81 } mat;
 82 
 83 void input(int n) {
 84     for (int i = 0; i < n; i++) {
 85         scanf("%d%d", &pt[i].x, &pt[i].y);
 86         pt[i].id = i;
 87         buf[i] = pt[i];
 88     }
 89 }
 90 
 91 bool diffLine(point &a, point &p, point &b) {
 92     return fabs(atan2(a.y - p.y, a.x - p.x) - atan2(b.y - p.y, b.x - p.x)) > eps;
 93 }
 94 
 95 void addEdge(int &a, int &b) {
 96     mat.val[a][b]--;
 97     mat.val[a][a]++;
 98 }
 99 
100 void makeMat(int n, int r) {
101     mat = Mat();
102     for (int i = 0; i < n; i++) {
103         p0 = buf[i];
104         sort(pt, pt + n, cmp);
105         if (dis2(pt[1], p0) <= r) {
106             addEdge(pt[1].id, p0.id);
107         }
108         for (int j = 2; j < n; j++) {
109             if (diffLine(pt[j - 1], p0, pt[j])) {
110                 if (dis2(pt[j], p0) <= r) {
111                     addEdge(pt[j].id, p0.id);
112                 }
113             }
114         }
115 //        for (int j = 0; j < n; j++) {
116 //            printf("%d %d\n", pt[j].x, pt[j].y);
117 //        }
118 //        puts("~~~");
119     }
120 //    mat.print();
121 //    puts("!!!");
122 }
123 
124 bool vis[maxn];
125 
126 void dfs(int x) {
127 
128     for (int i = 0; i < curSize; i++) {
129         if (vis[i]) continue;
130         if (mat.val[x][i]) {
131             vis[i] = true;
132             dfs(i);
133         }
134     }
135 }
136 
137 bool check(int n) {
138     memset(vis, false, sizeof(vis));
139     vis[0] = true;
140     dfs(0);
141     for (int i = 0; i < n; i++) {
142         if (!vis[i]) return false;
143     }
144 
145     return true;
146 }
147 
148 int main() {
149     int T;
150     int n, m;
151 
152 //    freopen("in", "r", stdin);
153     scanf("%d", &T);
154     while (T--) {
155         scanf("%d%d", &n, &m);
156         curSize = n;
157         input(n);
158         makeMat(n, m * m);
159 
160         if (check(n)) {
161             int ans = mat.det();
162 
163             printf("%d\n", ans);
164         } else puts("-1");
165     }
166 
167     return 0;
168 }

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/hdu_4305_Lyon.html