Atcoder Beginner Contest 178 E,F 题解
E - Dist Max
题意
给出 n 个点的坐标(坐标均为整数),求出曼哈顿距离最大的两个点的距离,两个点的曼哈顿距离为(|x_1-x_2|+|y_1-y_2|)。
题解
这道题又让我想起来,我之前说过的一句话,看到题目中给出公式,一定要化简试试。愣是没有想起来
去掉曼哈顿距离中的绝对值符号,4种情况:
- (x_1-x_2+y_1-y_2 = (x_1+y_1)-(y_1+y_2))
- (x_2-x_1+y_1-y_2=(x_2-y_2) - (x_1-y_1))
- (x_1-y_1+y_2-y_1=(x_1-y_1)-(x_2-y_2))
- (x_2-x_1+y_2-y_1=(x_2+y_2)-(x_1+y_1))
第 1 种情况和第 4 种情况一样
第 2 种情况和第 3 种情况一样
所以答案一定在 3,4 中产生。
我们只需要求出(x+y)的最大值、最小值,(x-y)的最大值、最小值。
输出较大的差值即可。
代码
/*
* @Autor: valk
* @Date: 2020-04-04 14:56:12
* @LastEditTime: 2020-09-17 20:07:08
* @Description: 如果邪恶 是华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
*/
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 1e9 + 7;
const ll seed = 12289;
const double eps = 1e-6;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e3 + 10;
int main()
{
int n;
scanf("%d", &n);
ll maxn1 = -inf, maxn2 = -inf, minn1 = inf, minn2 = inf;
for (ll i = 1; i <= n; i++) {
ll x, y;
scanf("%lld%lld", &x, &y);
ll sum = x + y;
ll dis = x - y;
maxn1 = max(maxn1, sum);
minn1 = min(minn1, sum);
maxn2 = max(maxn2, dis);
minn2 = min(minn2, dis);
}
printf("%lld
", max(maxn1 - minn1, maxn2 - minn2));
return 0;
}
F - Contrast
题意
给定两个长度相同,都按照升序排序的序列 a ,b ,问是否可以通过重排第二个序列,使得对于任意 (i) ,(a_i!=b_i)。
思路
刚开始,直接把 b 序列放到 set 中,每次取出最大的和当前 a 序列的值比较,如果不相等,这个值就放到当前位置。否则取前一个,如果当前是 set 的开头,那么就不可能满足题目要求。
后来一想可以通过和前面的交换一下来使这个满足。但是用什么如何找到前面符合标准的是个问题,怎么写复杂度都达不到。
看题解之后,恍然大悟。
题解首先是把 b 序列整个翻转过来,一一匹配,中间可能有一段区间([l,r]) a 序列和 b 序列相同,并且都是一个数字,那么这些位置就和其他位置交换,思路看着倒是差不多,但是这个很骚。交换的时候只需要判断不是区间 ([l,r]) 的位置即可。
代码
/*
* @Autor: valk
* @Date: 2020-07-17 16:50:40
* @LastEditTime: 2020-09-19 17:27:22
* @Description: 如果邪恶 是华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
*/
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const int seed = 12289;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 10;
int arr[N], brr[N];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &arr[i]);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &brr[n - i + 1]);
}
int pos = 1, flag = 1;
for (int i = 1; i <= n; i++) {
if (arr[i] == brr[i]) {
while (pos <= n && (arr[i] == brr[pos] || arr[i] == arr[pos])) {
pos++;
}
if (pos > n) {
flag = 0;
break;
}
swap(brr[pos], brr[i]);
}
}
if (!flag) {
printf("No
");
} else {
printf("Yes
");
for (int i = 1; i <= n; i++) {
printf("%d ", brr[i]);
}
printf("
");
}
return 0;
}