在麥克雷的面前有n個數,以及乙個r*c的矩陣。現在他的任務是從n個數中取出r*c個,並填入這個矩陣中。矩陣每一行的法值為本行最大值與最小值的差,而整個矩陣的法值為每一行的法值的最大值。現在,麥克雷想知道矩陣的最小法值是多少。
顯然排序後選擇答案是不會影響答案的,分析題意後可以發現乙個明顯的性質:對於某乙個數,假設它是一行中最小的值,那麼對於有序序列中,最大值一定是它的位置-c+1的那個數。想到能夠二分答案,但是因為直接二分的複雜度是lo
g109 ,我們可以處理出相鄰的差值,在其中二分。在乙個有序序列中,容易證明,當以當前值作為某一行的最小值時,若差值小於二分出來的,一定選擇是最優的,統計有多少個滿足的區間,若數量≥r,那麼就是合法的,注意區間不能重疊。
var
a,f:array[0..500000] of longint;
n,p,q,i,l,r,mid,ans,sum:longint;
procedure
qsort
(l,r:longint);
var i,j,mid:longint;
begin
i:=l;j:=r;
mid:=a[(l+r)div
2]; repeat
while a[i]do inc(i);
while middo dec(j);
if i<=j then
begin
a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
inc(i); dec(j);
end;
until i>j;
if ithen qsort(i,r);
if lthen qsort(l,j);
end;
function
pd(x:longint):boolean;
var i:longint;
begin
sum:=0;i:=0;
while i1
dobegin
inc(i);
if f[i]>x then
continue;
inc(sum);i:=i+q-1;
if sum>=p then
exit(true);
end;
if sum>=p then
exit(true);exit(false);
end;
begin
readln(n,p,q);
for i:=1
to n do
read(a[i]);
qsort(1,n);
for i:=1
to n-q+1
dobegin
f[i]:=a[i+q-1]-a[i];
a[i]:=a[i+q-1]-a[i];
end;
qsort(1,n-1);
l:=1;r:=n-1;
while ldo
begin
mid:=(l+r)div
2; if pd(a[mid]) then
begin
ans:=a[mid];
r:=mid-1;
endelse l:=mid+1;
end;
if pd(a[l]) and(ans>a[l]) then ans:=a[l];
writeln(ans);
end.
NOIP 2002提高組 選數 dfs 暴力
2002年noip全國聯賽普及組 時間限制 1 s 空間限制 128000 kb 題目等級 gold 題目描述 description 已知 n 個整數 x1,x2,xn,以及乙個整數 k k n 從 n 個整數中任選 k 個整數相加,可分別得到一系列的和。例如當 n 4,k 3,4 個整數分別為 ...
NOIP2002 普及組 選數
題目描述 已知 n 個整數 x1,x2,xn,以及乙個整數 k k n 從 n 個整數中任選 k 個整數相加,可分別得到一系列的和。例如當 n 4,k 3,4 個整數分別為 3,7,12,19 時,可得全部的組合與它們的和為 3 7 12 22 3 7 19 29 7 12 19 38 3 12 1...
NOIP提高組 矩陣
在麥克雷的面前出現了乙個有n m個格仔的矩陣,每個格仔用 或 表示,表示這個格仔可以放東西,則表示這個格仔不能放東西。現在他拿著一條1 2大小的木棒,好奇的他想知道對於一些子矩陣,有多少種放木棒的方案。因為棍子是1 2的,所以很容易就能發現,兩個被分割的塊,除了跨越兩個塊擺放木棍的方案數會對答案有影...