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 }
思路2:
可以证明得到:白色与黑色相交方块的左下角坐标是:(max(x1, x3), max(y1, y3)) 右下角坐标是(min(x2, x4), min(y2, y4))