所谓的日常 #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 }
div.1
给出一个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 }