1. 程式人生 > >Chtholly Nota Seniorious

Chtholly Nota Seniorious

調整 消失 math for 鏈接 不用 說明 amp 人才

題目背景

大樣例下發鏈接: 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號島上的景色竟與地上的森林無異。轉念又想,黃金妖精本身就是與森林之中出現,成長,消亡的神秘存在啊。

時間不早了,早上訓練中落敗的珂朵莉即將回來了。您要盡快和威廉一起調整好聖劍,千萬不能遲喲。

輸入輸出格式

輸入格式:

第一行兩個自然數n,mn,m

接下來nn行,每行mm個自然數A_{i,j}Ai,j?表示權值

輸出格式:

一個整數表示答案。

輸入輸出樣例

輸入樣例#1:
4 4
1 12 6 11
11 4 2 14
10 1 9 20
4 17 13 10
輸出樣例#1:
11

說明

樣例解釋

1  12 6        11
11 4  2        14
10 1  9        20
4        17 13 10

分法不唯一,如圖是一種合法的分法。左邊部分極差12-1=11,右邊一塊極差20-10=10,所以答案取這兩個中較大者11。沒有別的分法,可以使答案更小。

數據範圍與約定

測試點  n    m    
#1-2 \le 1010 \le 1010
#3-4 1 \le 20002000
#5-7 \le 200200 \le 200200
#8-10 \le 20002000 \le 20002000

對於所有的權值1\le A_{i,j} \le 10^91Ai,j?109

我們需要按行掃這個矩陣兩遍,第一遍從上往下掃,第二遍從下往上掃。

基於貪心的原則,對於每一行,我們從右往左掃。當遇到這一行第一個(最靠右的一個)滿足的格子的時候停止,然後下一行從同一個位置開始往左掃。這樣貪心可以保證滿足條件的同時給下一行更多的選擇。

把左邊的部分記為A部分,右邊的部分記為B部分,則掃的時候順便維護下每一部分掃到上一行為止的最大最小值,在掃這行的過程中就判斷下最大值減最小值會不會爆……

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int a[2001][2001],premax[2001][2001],premin[2001][2001];
 7 int sufmax[2001][2001],sufmin[2001][2001],n,m,ans;
 8 bool check1(int k)
 9 {int i,j;
10     int lim=m,maxa=0,mina=2e9,maxb=0,minb=2e9;
11     for (i=1;i<=n;i++)
12     {
13         int flag=0;
14         for (j=lim;j>=0&&flag==0;j--)
15         {
16             if (max(max(maxa,premax[i][j])-min(mina,premin[i][j]),max(maxb,sufmax[i][j+1])-min(minb,sufmin[i][j+1]))<=k)
17             {
18                 lim=j;
19                 maxa=max(premax[i][j],maxa);
20                 if (j+1<=m)
21                 maxb=max(sufmax[i][j+1],maxb);
22                 mina=min(premin[i][j],mina);
23                 if (j+1<=m)
24                 minb=min(sufmin[i][j+1],minb);
25                 flag=1;
26             }
27         }
28         if (flag==0) return 0;
29     }
30     return 1;
31 }
32 bool check2(int k)
33 {int i,j;
34     int lim=m,maxa=0,mina=2e9,maxb=0,minb=2e9;
35     for (i=n;i>=1;i--)
36     {
37         int flag=0;
38         for (j=lim;j>=0&&flag==0;j--)
39         {
40             if (max(max(maxa,premax[i][j])-min(mina,premin[i][j]),max(maxb,sufmax[i][j+1])-min(minb,sufmin[i][j+1]))<=k)
41             {
42                 lim=j;
43                 maxa=max(premax[i][j],maxa);
44                 if (j+1<=m)
45                 maxb=max(sufmax[i][j+1],maxb);
46                 mina=min(premin[i][j],mina);
47                 if (j+1<=m)
48                 minb=min(sufmin[i][j+1],minb);
49                 flag=1;
50             }
51         }
52         if (flag==0) return 0;
53     }
54     return 1;
55 }
56 int main()
57 {int i,j;
58   cin>>n>>m;
59   for (i=1;i<=n;i++)
60   for (j=1;j<=m;j++)
61   scanf("%d",&a[i][j]);
62   for (i=1;i<=n;i++)
63   {
64       premax[i][1]=premin[i][1]=a[i][1];
65       for (j=2;j<=m;j++)
66       {
67           premax[i][j]=max(premax[i][j-1],a[i][j]);
68           premin[i][j]=min(premin[i][j-1],a[i][j]);
69       }
70       sufmax[i][m]=sufmin[i][m]=a[i][m];
71       for (j=m-1;j>=1;j--)
72       {
73           sufmax[i][j]=max(sufmax[i][j+1],a[i][j]);
74           sufmin[i][j]=min(sufmin[i][j+1],a[i][j]);
75       }
76       sufmin[i][m+1]=premin[i][0]=2e9;
77   }
78       int l=0;int r=1e9;
79       while (l<=r)
80       {
81           int mid=(l+r)/2;
82           if (check1(mid)||check2(mid)) ans=mid,r=mid-1;
83           else l=mid+1;
84       }
85       cout<<ans;
86 }

Chtholly Nota Seniorious