LeCoz

导航

CodeForce Div 2 C. Masha and two friends

  题目链接: http://codeforces.com/contest/1080/problem/C

思路:双向延长两个矩形方块的4边,会形成一个被分割为9块的更大立方体。

计算所有的9个方框。方框中心的点只有可能在黑框,白框或者在外面。中心点在黑框中则按照黑色渲染了棋盘计算,其余同理。

详细见代码。

注意点:

1.题目上方框的信息给出的是方块号的信息而非坐标信息。需要转换成坐标信息

2.求两者的中点得用double转换,如果用float转换精度会有偏差。

3.sort函数应该是sort(x+1, x+5),心态崩了。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <cmath>
  5 #include <cstdio>
  6 #include <vector>
  7 #include <queue>
  8 #include <set>
  9 #include <map>
 10 #include <stack>
 11 #define ll long long
 12 //#define local
 13 
 14 using namespace std;
 15 
 16 const int MOD = 1e9+7;
 17 const int inf = 0x3f3f3f3f;
 18 const double PI = acos(-1.0);
 19 const int maxn = 3e5 + 10;
 20 ll x1, x2, x3, x4;
 21 ll y11, y2, y3, y4;
 22 
 23 int judge(ll lowx, ll lowy, ll highx, ll highy) {
 24     double x = double(lowx + highx)/2.0;
 25     double y = double(lowy + highy)/2.0;
 26     if (x>x3 && x < x4 && y > y3 && y < y4) {
 27         return 2;
 28     } else if (x>x1 && x < x2 && y > y11 && y < y2) {
 29         return 1;
 30     } else {
 31         return 0;
 32     }
 33 }
 34 
 35 int main() {
 36 #ifdef local
 37     if(freopen("/Users/Andrew/Desktop/data.txt", "r", stdin) == NULL) printf("can't open this file!\n");
 38 #endif
 39     
 40     int q;
 41     scanf("%d", &q);
 42     ll n, m;
 43     ll x[5], y[5];
 44     while (q--) {
 45         scanf("%lld%lld", &n, &m);
 46         ll white = n*m/2;
 47         ll black = n*m/2;
 48         if ((n*m) % 2) {
 49             white++;
 50         }
 51         scanf("%lld%lld%lld%lld", &x1, &y11, &x2, &y2);
 52         scanf("%lld%lld%lld%lld", &x3, &y3, &x4, &y4);
 53         x1 -= 1; x3 -= 1;
 54         y11 -= 1; y3 -= 1;
 55         x[1] = x1; x[2] = x2;
 56         x[3] = x3; x[4] = x4;
 57         sort(x+1,x+5);
 58         y[1] = y11; y[2] = y2;
 59         y[3] = y3; y[4] = y4;
 60         sort(y+1, y+5);
 61         for (int i = 1; i < 4; ++i) {
 62             for (int j = 1; j < 4; ++j) {
 63                 if (x[i+1]==x[i] || y[j+1]==y[j]) continue;
 64                 ll tmp = (x[i+1]-x[i])*(y[j+1]-y[j]);
 65                 if (judge(x[i], y[j], x[i+1], y[j+1]) == 0) {
 66                     continue;
 67                 } else if (judge(x[i], y[j], x[i+1], y[j+1]) == 1) {
 68                     if (tmp % 2) {
 69                         if ((x[i] + y[j]) % 2 == 0) {// white
 70                             white += tmp/2;
 71                             black -= tmp/2;
 72                         }
 73                         else {
 74                             white += tmp/2 + 1;
 75                             black -= (tmp/2+1);
 76                         }
 77                     } else {
 78                         white += tmp/2;
 79                         black -= tmp/2;
 80                     }
 81                 } else {
 82                     if (tmp % 2) {
 83                         if ((x[i] + y[j]) % 2 == 1) {// black
 84                             white -= tmp/2;
 85                             black += tmp/2;
 86                         }
 87                         else {
 88                             white -= (tmp/2+1);
 89                             black += (tmp/2+1);
 90                         }
 91                     } else {
 92                         white -= tmp/2;
 93                         black += tmp/2;
 94                     }
 95                 }
 96             }
 97         }
 98         printf("%lld %lld\n", white, black);
 99     }
100     
101 #ifdef local
102     fclose(stdin);
103 #endif
104     return 0;
105 }
View Code

 

思路2:

可以证明得到:白色与黑色相交方块的左下角坐标是:(max(x1, x3), max(y1, y3)) 右下角坐标是(min(x2, x4), min(y2, y4))

posted on 2018-11-24 22:48  LeCoz  阅读(189)  评论(0编辑  收藏  举报