首页 > 其他 > 详细

【Atcoder Beginner Contest 178】E-F

时间:2020-09-19 20:47:56      阅读:39      评论:0      收藏:0      [点我收藏+]

Atcoder Beginner Contest 178 E,F 题解

E - Dist Max

题意

给出 n 个点的坐标(坐标均为整数),求出曼哈顿距离最大的两个点的距离,两个点的曼哈顿距离为\(|x_1-x_2|+|y_1-y_2|\)

题解

这道题又让我想起来,我之前说过的一句话,看到题目中给出公式,一定要化简试试。愣是没有想起来

去掉曼哈顿距离中的绝对值符号,4种情况:

  1. \(x_1-x_2+y_1-y_2 = (x_1+y_1)-(y_1+y_2)\)
  2. \(x_2-x_1+y_1-y_2=(x_2-y_2) - (x_1-y_1)\)
  3. \(x_1-y_1+y_2-y_1=(x_1-y_1)-(x_2-y_2)\)
  4. \(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;
}

【Atcoder Beginner Contest 178】E-F

原文:https://www.cnblogs.com/valk3/p/13697395.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!