AtCoder ARC 109 D (拆点 + 分类讨论)

题目链接:https://atcoder.jp/contests/arc109/tasks/arc109_d

这个做法太妙了
注意到一个四方格内的 'L' 总共有四种形态,所以可以将四方格的左下角顶点拆成四个点,分别代表四种状态

方格间的转移情况如图:(不能沿对角线穿越两个不同的大格子)

如果在对角线上,那答案就是 \(max(x, y) + 1\), 否则答案就是 \(max(x, y)\), \(x, y\) 是新坐标(从 \(0\) 开始)

注意对负数的处理,总之来说就是,细节好多好多好多...

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;

const int maxn = 100010;

int T;

int ax, ay, bx, by, cx, cy;

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	T = read();
	while(T--){
		int flag_x = 0, flag_y = 0;
		ax = read(), ay = read(); 
		bx = read(), by = read();
		cx = read(), cy = read();
		
		if(ax < 0 || bx < 0 || cx < 0) flag_x = 1;
		if(ay < 0 || by < 0 || cy < 0) flag_y = 1;
		
		int tx, ty;
		tx = min(min(ax, bx), cx); ty = min(min(ay, by), cy);
		
		if(tx == 0 && ty == 0){
			if(ax + bx + cx == 1 && ay + by + cy == 1){
				printf("0\n");
			} else{
				printf("1\n");
			}
		} else{
			ax -= tx, ay -= ty;
			bx -= tx, by -= ty;
			cx -= tx, cy -= ty;
			
			int X = ax + bx + cx, Y = ay + by + cy;
	
			if(X == 1 && Y == 1){
				tx = 2 * tx, ty = 2 * ty;
				if(tx == ty){
					printf("%d\n", max(abs(tx), abs(ty)) + 1); 
				} else{
					printf("%d\n", max(abs(tx), abs(ty)));
				}
			} else if(X == 1 && Y == 2){
				tx = 2 * tx, ty = 2 * ty + 1;
				printf("%d\n", max(abs(tx), abs(ty)));
			} else if(X == 2 && Y == 1){
				tx = 2 * tx + 1, ty = 2 * ty;
				printf("%d\n", max(abs(tx), abs(ty)));
			} else{
				tx = 2 * tx + 1, ty = 2 * ty + 1;
				if(tx == ty){
					printf("%d\n", max(abs(tx), abs(ty)) + 1);
				} else{
					printf("%d\n", max(abs(tx), abs(ty)));	
				}
			}			
		}

	}
	return 0;
}
posted @ 2020-12-05 22:22  Tartarus_li  阅读(162)  评论(0编辑  收藏  举报