标签:选择 中心 题解 namespace targe 数据 inf 快速 max
时间限制 \(0.5s\) | 空间限制 \(64M\)
在一个新的游戏中,为了创建基于回合的战斗的地图,\(Petya\) 面临着以下问题。
地图是由六边形的单元组成的。由于地图很大,游戏设计师需要一个工具来快速的填充自己和敌人相同单元个数的地图。操作如下:游戏设计师在地图上选择一个方形区域,在这个被选中区域内的每个单元都属于敌人的单元。
更正式地说,如果游戏设计者选中的单元的坐标为 \((x_1,y_1)\) 和 \((x_2,y_2)\),其中 \(x_1 ≤ x_2\) 和 \(y_1 ≤ y_2\),那么所有以坐标 \((x,y)\) 为中心的 \(x_1 ≤ x_2\) 和 \(y_1 ≤ y_2\) 的单元格都将被填充。建立一个正交坐标系统,使一个单元边平行于 \(OX\) 轴,所有六边形中心坐标都为整数,对于每个整数 \(x\),都有以 \(x\) 坐标中心的单元,对于每个整数 \(y\),也都有以 \(y\) 为坐标中心的单元。\(x_2 - x_1\) 的差确保能被 \(2\) 整除。\(Petya\) 决定在绘制选定的单元之前,他希望输出计划在地图上绘制的单元的个数。帮助他在绘画前实现这些单元的计数。
数据范围:\(-?10^9?≤?x_1?≤?x_2?≤?10^9,??-?10^9?≤?y_1?≤?y_2?≤?10^9\)
我们发现:六边形在任意一种铺法中都有两种,而铺法总共也有两种。第一种铺法是,让一种六边形的中心的坐标为(奇数,奇数),让另一种六边形的中心的坐标为(偶数,偶数)。第二种铺法是,让一种六边形的中点的坐标为(奇数,偶数),让另一个六边形的中心的坐标为(偶数,奇数)。我们只需要对这两种答案取 \(max\) 即可。
那么如何计算这两种答案呢?我们观察发现:无论铺法如何,我们在矩形边界上的奇数坐标个数和偶数坐标个数都是相同的。我们可以先求出长上面的奇数坐标个数 \(cnt_1\),偶数坐标个数 \(cnt_2\),再求出宽上面的奇数坐标个数 \(cnt_3\),偶数坐标个数 \(cnt_4\)。然后答案就是 \(max(cnt_1 * cnt_3 + cnt_2 * cnt_4, cnt_1* cnt_4 +cnt_2 * cnt_3)\)。也就是让长上面的奇数坐标分别与宽上面的偶数坐标和奇数坐标配对。
#include <iostream>
using namespace std;
#define int long long
int x1, Y1, x2, Y2;
int x, y;
int cnt1, cnt2, cnt3, cnt4;
signed main()
{
cin >> x1 >> Y1 >> x2 >> Y2;
if (x1 % 2) cnt2 += (x2 - x1) / 2, cnt1 += (x2 - x1 + 1) - cnt2;
else cnt1 += (x2 - x1) / 2, cnt2 += (x2 - x1 + 1) - cnt1;
x = Y1;
y = Y2;
if (Y1 % 2)
{
cnt3++;
x++;
}
if (Y2 % 2)
{
cnt3++;
y--;
}
cnt3 += (y - x) / 2;
cnt4 = y - x + 1 - (y - x) / 2;
cout << max(cnt1 * cnt3 + cnt2 * cnt4, cnt1 * cnt4 + cnt2 * cnt3);
return 0;
}
标签:选择 中心 题解 namespace targe 数据 inf 快速 max
原文地址:https://www.cnblogs.com/david24/p/14449137.html