zoukankan      html  css  js  c++  java
  • 2013多校训练赛第三场 总结

    HDU 4621~4631

      今天的多校好变态,是IOI冠军出的题,把我们虐的半死了。

      简单讲一下今天的情况,今天就只做了两道水题,算是签了个到,然后就卡1011(HDU 4631)一个下午了。其实感觉今天1009的几何是可以做的,因为我之前也做过类似的题,不过最后还是因为没信心做,所以放弃了。目测是可以用PSLG来做1009的,不过当时计算了一下最坏复杂度,觉得会超时,一直没做。

      1011啱看上去是kd树,不过当时搞了好久都还是超时。开始的时候我直接上标准kd树,不带平衡功能的,各种超时。然后我就改成预处理整棵树,然后就用标记法来搞点的插入,理论上平均能达到O(log n)每次操作的,因为树的结点是固定下来的。不过最意想不到的是,这样做的kd树最后还是退化了,随便搞一组case就跑了个本地21s,虽然很多500k的数据还是能12s内出答案的。

      然后我就加上更多的标记,原来12s的变成7s了,优化了不少。然后还是被我找到要20s+才能出答案的数据。。。_(:з」∠)_这题就一直卡到最后了。

    今天0贡献,代码不用队友的,重写了一遍:

    4631 ( Sad Love Story )

      居然用set能过,真是大开眼界了。

     1 #include <iostream>
     2 #include <set>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <ctime>
     7 
     8 using namespace std;
     9 
    10 typedef long long LL;
    11 typedef pair<int, int> PII;
    12 template<class T> T sqr(T x) { return x * x;}
    13 LL dist(PII a, PII b) { return sqr((LL) a.first - b.first) + sqr((LL) a.second - b.second);}
    14 #define ITOR iterator
    15 set<PII> pts;
    16 
    17 int main() {
    18     int T, n;
    19     int ax, bx, cx, ay, by, cy;
    20     cin >> T;
    21     while (T--) {
    22         cin >> n >> ax >> bx >> cx >> ay >> by >> cy;
    23         //time_t t1 = clock();
    24         pts.clear();
    25         int x = 0, y = 0;
    26         LL sum = 0, mn = 1ll << 62, dis;
    27         set<PII>::ITOR si, c;
    28         PII cur;
    29         for (int i = 0; i < n; i++) {
    30             x = ((LL) ax * x + bx) % cx;
    31             y = ((LL) ay * y + by) % cy;
    32             cur = PII(x, y);
    33             if (mn == 0) break;
    34             if (pts.find(cur) != pts.end()) { mn = 0; break;}
    35             pts.insert(cur);
    36             c = si = pts.find(cur);
    37             c++;
    38             while (c != pts.end()) {
    39                 dis = dist(cur, *c);
    40                 mn = min(mn, dis);
    41                 if (sqr((LL) (*c).first - cur.first) >= mn) break;
    42                 c++;
    43             }
    44             c = si;
    45             while (true) {
    46                 if (c == pts.begin()) break;
    47                 c--;
    48                 dis = dist(cur, *c);
    49                 mn = min(mn, dis);
    50                 if (sqr((LL) (*c).first - cur.first) >= mn) break;
    51             }
    52             if (i) sum += mn;
    53         }
    54         cout << sum << endl;
    55         //cout << "time " << (double) (clock() - t1) / CLOCKS_PER_SEC << endl;
    56     }
    57     return 0;
    58 }
    View Code

    4628 ( Pieces )

      直接状态压缩然后暴力dp枚举子集,for (int j = i; j; j = (j - 1) & i) ;

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstring>
     5 
     6 using namespace std;
     7 
     8 const int N = 1 << 16;
     9 bool vis[N];
    10 int dp[N], top;
    11 char str[22], cur[22];
    12 
    13 bool check() {
    14     int s = 0, t = top;
    15     while (s < t) if (cur[s++] != cur[t--]) return false;
    16     return true;
    17 }
    18 
    19 void dfs(int p, int len, int st) {
    20     if (p >= len) {
    21         if (check()) vis[st] = true;
    22         return ;
    23     }
    24     cur[++top] = str[p];
    25     dfs(p + 1, len, st | 1 << p);
    26     top--;
    27     dfs(p + 1, len, st);
    28 }
    29 
    30 int DP(int len) {
    31     memset(dp, 127, sizeof(dp));
    32     dp[0] = 0;
    33     for (int i = 1, e = 1 << len; i < e; i++) {
    34         for (int j = i; j; j = (j - 1) & i) {
    35             if (vis[j]) dp[i] = min(dp[i ^ j] + 1, dp[i]);
    36         }
    37     }
    38     return dp[(1 << len) - 1];
    39 }
    40 
    41 
    42 int main() {
    43     int T;
    44     cin >> T;
    45     while (T-- && cin >> str) {
    46         memset(vis, 0, sizeof(vis));
    47         top = -1;
    48         dfs(0, strlen(str), 0);
    49         //for (int i = 0; i < (1 << strlen(str)); i++) cout << i << ' ' << vis[i] << endl;
    50         cout << DP(strlen(str)) << endl;
    51     } 
    52     return 0;
    53 }
    View Code

    4627 ( The Unsolvable Problem )

      分3种情况,一种是奇数的时候,直接分解成n/2和n/2+1相乘即可,偶数有两种,其实就是枚举(n/2-1)和(n/2+1)、(n/2-2)和(n/2+2)两个的gcd。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 
     6 using namespace std;
     7 
     8 typedef long long LL;
     9 inline LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a;}
    10 inline LL lcm(LL a, LL b) { return a / gcd(a, b) * b;}
    11 
    12 int main() {
    13     int T;
    14     LL n;
    15     cin >> T;
    16     while (T-- && cin >> n) {
    17         if (n & 1) cout << (n >> 1) * ((n >> 1) + 1) << endl;
    18         else {
    19             LL m = n >> 1, ans = m;
    20             for (int i = 1; i <= 2; i++) {
    21                 if (m - i <= 0) break;
    22                 ans = max(ans, lcm(m + i, m - i));
    23             }
    24             cout << ans << endl;
    25         }
    26     }
    27     return 0;
    28 }
    View Code

      总的来说,这次就是被惨虐。一个原因是最近在恶补基础,没有锻炼思维的灵活性,题目稍微变形就只会死板的解题是不行的。在补完基础以后再加强一下!

    UPD:

    4629(Burning)

      PSLG简单模型。

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <vector>
      8 #include <map>
      9 #include <set>
     10 
     11 using namespace std;
     12 
     13 const int N = 11111;
     14 const double EPS = 1e-8;
     15 template<class T> T sqr(T x) { return x * x;}
     16 inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
     17 struct Point {
     18     double x, y;
     19     int id;
     20     Point() {}
     21     Point(double x, double y) : x(x), y(y) {}
     22     Point operator + (Point a) { return Point(x + a.x, y + a.y);}
     23     Point operator - (Point a) { return Point(x - a.x, y - a.y);}
     24     Point operator * (double p) { return Point(x * p, y * p);}
     25     Point operator / (double p) { return Point(x / p, y / p);}
     26     bool operator < (Point a) const { return sgn(x - a.x) < 0 || sgn(x - a.x) == 0 && y < a.y;}
     27     bool operator == (Point a) const { return sgn(x - a.x) == 0 && sgn(y - a.y) == 0;} 
     28 } ips[N];
     29 
     30 inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
     31 inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y;}
     32 inline double veclen(Point x) { return sqrt(dot(x, x));}
     33 inline Point vecunit(Point x) { return x / veclen(x);}
     34 inline Point normal(Point x) { return Point(-x.y, x.x) / veclen(x);}
     35 
     36 struct Line {
     37     Point s, t;
     38     Line() {}
     39     Line(Point s, Point t) : s(s), t(t) {}
     40     Point vec() { return t - s;}
     41     Point point(double d) { return s + vec() * d;}
     42 } ;
     43 
     44 inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));}
     45 inline bool onseg(Point x, Point a, Point b) { return sgn(cross(a - x, b - x)) == 0 && sgn(dot(a - x, b - x)) <= 0;}
     46 
     47 int ptinpoly(Point p, Point *pt, int n) {
     48     int wn = 0;
     49     pt[n] = pt[0];
     50     for (int i = 0; i < n; i++) {
     51         if (onseg(p, pt[i], pt[i + 1])) return -1;
     52         int k = sgn(cross(pt[i + 1] - pt[i], p - pt[i]));
     53         int d1 = sgn(pt[i].y - p.y);
     54         int d2 = sgn(pt[i + 1].y - p.y);
     55         if (k > 0 && d1 <= 0 && d2 > 0) wn++;
     56         if (k < 0 && d2 <= 0 && d1 > 0) wn--;
     57     }
     58     return wn != 0;
     59 }
     60 
     61 Point tri[55][4], pts[222];
     62 typedef pair<double, int> PDI;
     63 typedef pair<int, int> PII;
     64 vector<PDI> rel[N];
     65 map<int, int> nxp[N];
     66 set<PII> vis;
     67 double ans[55];
     68 
     69 inline double angle(Point x) { return atan2(x.y, x.x);}
     70 bool operator < (PDI a, PDI b) { return sgn(a.first - b.first) < 0 || sgn(a.first - b.first) == 0 && a.second < b.second;}
     71 bool operator == (PDI a, PDI b) { return sgn(a.first - b.first) == 0 && a.second == b.second;}
     72 
     73 int main() {
     74     //freopen("in", "r", stdin);
     75     int T, n, m;
     76     scanf("%d
    ", &T);
     77     while (T-- && ~scanf("%d", &n)) {
     78         m = 0;
     79         for (int i = 0; i < n; i++) {
     80             for (int j = 0; j < 3; j++) {
     81                 scanf("%lf%lf", &tri[i][j].x, &tri[i][j].y);
     82                 ips[m++] = tri[i][j];
     83             }
     84             tri[i][3] = tri[i][0];
     85         }
     86         Line a, b;
     87         for (int i = 0; i < n; i++) {
     88             for (int j = 0; j < 3; j++) {
     89                 a = Line(tri[i][j], tri[i][j + 1]);
     90                 for (int x = i + 1; x < n; x++) {
     91                     if (i == x) continue;
     92                     for (int y = 0; y < 3; y++) {
     93                         b = Line(tri[x][y], tri[x][y + 1]);
     94                         if (sgn(cross(a.vec(), b.vec()))) {
     95                             ips[m] = llint(a, b);
     96                             if (onseg(ips[m], a.s, a.t) && onseg(ips[m], b.s, b.t)) m++;
     97                         }
     98                     }
     99                 }
    100             }
    101         }
    102         sort(ips, ips + m);
    103         m = (int) (unique(ips, ips + m) - ips);
    104         for (int i = 0; i < m; i++) ips[i].id = i, rel[i].clear(), nxp[i].clear();
    105         for (int i = 0; i < n; i++) {
    106             for (int j = 0; j < 3; j++) {
    107                 int t = 0;
    108                 for (int k = 0; k < m; k++) {
    109                     if (onseg(ips[k], tri[i][j], tri[i][j + 1])) pts[t++] = ips[k];
    110                 }
    111                 sort(pts, pts + t);
    112                 for (int i = 1; i < t; i++) {
    113                     rel[pts[i].id].push_back(PDI(angle(pts[i - 1] - pts[i]), pts[i - 1].id));
    114                     rel[pts[i - 1].id].push_back(PDI(angle(pts[i] - pts[i - 1]), pts[i].id));
    115                 }
    116             }
    117         }
    118         for (int i = 0; i < m; i++) {
    119             sort(rel[i].begin(), rel[i].end());
    120             int t = (int) (unique(rel[i].begin(), rel[i].end()) - rel[i].begin());
    121             while (rel[i].size() > t) rel[i].pop_back();
    122             if (t) {
    123                 rel[i].push_back(rel[i][0]);
    124                 for (int j = 0; j < t; j++) nxp[rel[i][j + 1].second][i] = rel[i][j].second;
    125                 rel[i].pop_back();
    126             }
    127         }
    128         vis.clear();
    129         memset(ans, 0, sizeof(ans));
    130         Point mid, nor;
    131         for (int i = 0, t; i < m; i++) {
    132             int sz = rel[i].size();
    133             for (int j = 0; j < sz; j++) {
    134                 if (vis.find(PII(i, rel[i][j].second)) != vis.end()) continue;
    135                 double tmp = 0;
    136                 int c = i, nx = rel[i][j].second;
    137                 while (vis.find(PII(c, nx)) == vis.end()) {
    138                     tmp += cross(ips[c], ips[nx]);
    139                     vis.insert(PII(c, nx));
    140                     t = c, c = nx, nx = nxp[t][c];
    141                 }
    142                 c = i, nx = rel[i][j].second;
    143                 nor = normal(ips[nx] - ips[c]) * 1e-4;
    144                 mid = (ips[c] + ips[nx]) / 2 + nor;
    145                 int cnt = 0;
    146                 for (int i = 0; i < n; i++) {
    147                     if (ptinpoly(mid, tri[i], 3)) cnt++;
    148                 }
    149                 ans[cnt] += tmp;
    150             }
    151         }
    152         for (int i = 1; i <= n; i++) printf("%.6f
    ", ans[i] / 2);
    153     }
    154     return 0;
    155 }
    View Code

    ——written by Lyon

  • 相关阅读:
    新建MDK工程
    winform如何打开电脑自带小软件
    Winform界面适应不同分辨率
    c#如何为pictureBox控件写单击事件
    winform如何获取记事本内容显示在listBox控件中
    winform如何单击X按钮弹出对话框
    win10系统如何使用自带的备份功能
    模拟iis账号权限
    (转发)在ASP.NET MVC中以post方式传递数组参数的示例
    .net开发windows服务小结 (转发)
  • 原文地址:https://www.cnblogs.com/LyonLys/p/2013_07_31_Lyon.html
Copyright © 2011-2022 走看看