zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    〖Linux〗Kubuntu设置打开应用时就只在打开时的工作区显示
    〖Linux〗Kubuntu, the application 'Google Chrome' has requested to open the wallet 'kdewallet'解决方法
    unity, dll is not allowed to be included or could not be found
    android check box 自定义图片
    unity, ios skin crash
    unity, Collider2D.bounds的一个坑
    unity, ContentSizeFitter立即生效
    类里的通用成员函数应声明为static
    unity, Gizmos.DrawMesh一个坑
    直线切割凹多边形
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_4305_Lyon.html
Copyright © 2011-2022 走看看