zoukankan      html  css  js  c++  java
  • noip模拟赛 Chtholly Nota Seniorious

    题目背景

    大样例下发链接: https://pan.baidu.com/s/1nuVpRS1 密码: sfxg

    こんなにも、たくさんの幸せをあの人に分けてもらった

    だから、きっと

    今の、私は

    谁が何と言おうと

    世界一、幸せな女の子だ

    题目描述

    ——“假如……我是说假如喔。

    万一我再过五天就会死,你能不能对我温柔一点?”

    巨大的六号兽五天后将袭击浮游大陆。

    无数次计算得到的残酷数据表明,只有圣剑瑟尼欧尼斯的适格精灵——珂朵莉·诺塔·瑟尼欧尼斯(Chtholly Nota Seniorious)开启妖精乡之门,才可以以生命为代价守住浮游岛。

    “至少,我也希望自己不用消失,也想让别人记住。我也想留下羁绊啊。”

    留给妖精少女珂朵莉的时间似乎已经不多了。

    年轻的二等技官,妖精仓库的管理员,世界上最后一个人类——威廉·克梅修,数百年前曾经是一名准勇者,掌握着成为一名勇者所需要的所有知识。

    大战在即,调整圣剑的状态成为了一项重要的任务。

    瑟尼欧里斯(セニオリス)
    圣剑的其中之一,在现存的遗迹兵装中,拥有最强大的力量。
    拥有非常特殊的资质,只有极少一部分的人才能使用。
    由四十一个护符组成。能将所有事物包含不死者都回归「死亡」。

    威廉需要调整圣剑的状态,因此他将瑟尼欧尼斯拆分护符,组成了一个nn行mm列的矩阵。

    每一个护符都有自己的魔力值。现在为了测试圣剑,你需要将这些护符分成 A,B两部分。

    要求如下:

    1. 圣剑的所有护符,恰好都属于两部分中的一部分。

    2. 每个部分内部的方块之间,可以通过上下左右相互到达,而且每个内部的方块之间互相到达,最多允许拐一次弯。

    例如

    AAAAA  AAAAA  AAAAA
    AABAA  BaAAA  AAABB
    ABBBA  BBAAA  AAABB
    AABAA  BaAAA  ABBBB
    AAAAA  AAAAA  BBBBB
    
      (1)     (2)     (3)      

    其中(1)(2)是不允许的分法,(3)是允许的分法。在(2)中,a属于A区域,这两个a元素之间互相到达,没有办法最多只拐一次弯。

    现在要问,所有合法的分法中,A区域的极差与B区域的极差 中间较大的一个的 最小值 是多少?

    好心而可爱的在一旁默默观察奈芙莲悄悄地告诉你,极差就是区域内最大值减去最小值。

    夜晚的风吹拂着,68号岛上的景色竟与地上的森林无异。转念又想,黄金妖精本身就是与森林之中出现,成长,消亡的神秘存在啊。

    时间不早了,早上训练中落败的珂朵莉即将回来了。您要尽快和威廉一起调整好圣剑,千万不能迟哟。

    分析:把图分成两个部分其实就相当于画一条单调的线:,为了使得极差最小,最大值和最小值肯定不在同一部分,先假设最大值在蓝色部分,最小值在红色部分。要求最大极差最小,可以想到二分答案,判断的时候一行一行的判断,看蓝色部分最多能够从右往左延伸到哪里,接下来判断其它的红色部分能否满足条件就行了.如果答案是k,蓝色区域都≥x-k,红色区域都≤y+k,x是最大值,y是最小值.

          每次二分求出来的只是一种情况,红蓝对调需要翻折一次,分割线单调上升或下降也需要翻折一次,也就是说把图形旋转4次求得最小值才是答案.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int inf = 0x7fffffff;
    
    int n, m, a[2010][2010], ans = inf, maxx = -inf, minn = inf;
    
    void turnl()
    {
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m / 2; j++)
                swap(a[i][j], a[i][m - j + 1]);
    }
    
    void turnn()
    {
        for (int i = 1; i <= n / 2; i++)
            for (int j = 1; j <= m; j++)
                swap(a[i][j], a[n - i + 1][j]);
    }
    
    bool check(int x)
    {
        int p = 0;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
                if (a[i][j] < maxx - x)
                    p = max(p, j);
            for (int j = 1; j <= m; j++)
                if (minn + x < a[i][j])
                    if (j <= p)
                        return false;
        }
        return true;
    }
    
    int solve()
    {
        int l = 0, r = maxx - minn, res = 0;
        while (l <= r)
        {
            int mid = (l + r) >> 1;
            if (check(mid))
            {
                res = mid;
                r = mid - 1;
            }
            else
                l = mid + 1;
        }
        return res;
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
            {
                scanf("%d", &a[i][j]);
                minn = min(minn, a[i][j]);
                maxx = max(maxx, a[i][j]);
            }
        ans = min(ans, solve());
        turnl();
        ans = min(ans, solve());
        turnn();
        ans = min(ans, solve());
        turnl();
        ans = min(ans, solve());
        printf("%d
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    matlab cell
    matlab linux 快捷键设置——有问题还是要解决
    latex 小结
    TOJ 1258 Very Simple Counting
    TOJ 2888 Pearls
    HDU 1248 寒冰王座
    TOJ 3486 Divisibility
    TOJ 3635 过山车
    TOJ 1840 Jack Straws
    HDU 4460 Friend Chains
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7705975.html
Copyright © 2011-2022 走看看