所谓的日常 #1 - 宴桃園豪傑三結義 斬黃巾英雄首立功

div.2 

CodeForces 467A George and Accommodation

给定n(<= 100)对(pi,qi),问有多少个i满足qi - pi >= 2。

照着题意写就可以了,算是给大家道题练练手啦。

 1 #include <stdio.h>
 2 
 3 int main() {
 4     int n;
 5     scanf("%d",&n);
 6     int answer = 0;
 7     for (int i = 0; i < n; ++ i) {
 8         int p,q;
 9         scanf("%d%d",&p,&q);
10         if (q - p >= 2) {
11             answer ++;
12         }
13     }
14     printf("%d\n",answer);
15 }
View Code

 

div.1

HDU 4056 Draw a Mess

给出一个200 * 50000的像素点矩阵,执行50000次操作,每次把一个矩形/圆形/菱形/三角形内的像素点涂成指定颜色,问最后每种颜色的数量。

这个题,乍一看的做法是200棵支持区间更新的线段树,时间复杂度是O(nqlogm),已经2e8了,再算上线段树本身的常数,虽然给了5秒的时限但我觉得还是不太能通过的。

事实上,如果把所有的操作先读进来,从后往前做,对于每个像素点,在它第一次被染色后就把它删掉,那么整体的复杂度就是O(nm + nq)了。

这里需要一种能够O(1)删除的数据结构,那么双向链表是一个选择。

然而双向链表需要引入其他的数据结构来辅助已删除节点的定位,比如并查集...

这里推荐一种好写的做法,用并查集来维护,每次把一个像素点染色后,就把它连向它右边的像素点。

  1 #include <bits/stdc++.h>
  2 typedef long long LL;
  3 
  4 int next[200 + 1][50000 + 1];
  5 int n,m,nq;
  6 
  7 const int N = 50000 + 5;
  8 char op[N];
  9 int var[N][5];
 10 int answer[9 + 1];
 11 
 12 int find(int *next,int x) {
 13     return x == next[x] ? x : next[x] = find(next,next[x]);
 14 }
 15 
 16 LL sqr(LL x) {
 17     return x * x;
 18 }
 19 
 20 void paint(int c,int x,int l,int r) {
 21     if (l < 0) l = 0;
 22     if (r > m - 1) r = m - 1;
 23     for (int i = find(next[x],l); i <= r; next[x][i] = i + 1,i = find(next[x],i)) {
 24         answer[c] ++;
 25     }
 26 }
 27 
 28 void work() {
 29     for (int i = 0; i < n; ++ i) {
 30         for (int j = 0; j <= m; ++ j) {
 31             next[i][j] = j;
 32         }
 33     }
 34     memset(answer,0,sizeof(answer));
 35 
 36     for (int q = nq - 1; q >= 0; -- q) {
 37         if (op[q] == 'C') {
 38             int xc = var[q][0],
 39                 yc = var[q][1],
 40                 r = var[q][2],
 41                 c = var[q][3];
 42             for (int x = 0; x < n; ++ x) {
 43                 if (sqr(x - xc) > sqr(r)) continue;
 44                 int dy = (int)(sqrt(sqr(r) - sqr(x - xc)) + 1e-8);
 45                 paint(c,x,yc - dy,yc + dy);
 46             }
 47         } else if (op[q] == 'D') {
 48             int xc = var[q][0],
 49                 yc = var[q][1],
 50                 r = var[q][2],
 51                 c = var[q][3];
 52             for (int x = 0; x < n; ++ x) {
 53                 if (std::abs(x - xc) > r) continue;
 54                 int dy = r - std::abs(x - xc);
 55                 paint(c,x,yc - dy,yc + dy);
 56             }
 57         } else if (op[q] == 'R') {
 58             int xc = var[q][0],
 59                 yc = var[q][1],
 60                 l = var[q][2],
 61                 w = var[q][3],
 62                 c = var[q][4];
 63             for (int x = 0; x < n; ++ x) {
 64                 if (x < xc || x > xc + l - 1) continue;
 65                 paint(c,x,yc,yc + w - 1);
 66             }
 67         } else {
 68             int xc = var[q][0],
 69                 yc = var[q][1],
 70                 w = var[q][2],
 71                 c = var[q][3];
 72             for (int x = 0; x < n; ++ x) {
 73                 if (x < xc || x > xc + w / 2) continue;
 74                 int dy = w / 2 - (x - xc);
 75                 paint(c,x,yc - dy,yc + dy);
 76             }
 77         }
 78     }
 79 }
 80 
 81 int main() {
 82     while (scanf("%d%d%d",&n,&m,&nq) == 3) {
 83         for (int i = 0; i < nq; ++ i) {
 84             char str[10 + 5];
 85             scanf("%s",str);
 86             op[i] = str[0];
 87             for (int j = 0; j < 4; ++ j) {
 88                 scanf("%d",&var[i][j]);
 89             }
 90             if (op[i] == 'R') {
 91                 scanf("%d",&var[i][4]);
 92             }
 93         }
 94         work();
 95         for (int i = 1; i <= 9; ++ i) {
 96             if (i != 1) putchar(' ');
 97             printf("%d",answer[i]);
 98         }
 99         puts("");
100     }
101 }
View Code

 

posted @ 2015-12-17 21:45  zstuACM  阅读(245)  评论(0编辑  收藏  举报