【Atcoder Beginner Contest 178】E-F
阿新 • • 發佈:2020-09-19
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\n", 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\n");
} else {
printf("Yes\n");
for (int i = 1; i <= n; i++) {
printf("%d ", brr[i]);
}
printf("\n");
}
return 0;
}