1. 程式人生 > >UOJ #206. 【APIO2016】Gap

UOJ #206. 【APIO2016】Gap

msu 一行 本地 信息 erl nbsp lns 有趣的 ref

NN 個嚴格遞增的非負整數 a1,a2,,aNa1,a2,…,aN(0a1<a2<?<aN10180≤a1<a2<?<aN≤1018)。你需要找出 ai+1aiai+1−ai(0iN10≤i≤N−1)裏的最大的值。

你的程序不能直接讀入這個整數序列,但是你可以通過給定的函數來查詢該序列的信息。關於查詢函數的細節,請根據你所使用的語言,參考下面的實現細節部分。

你需要實現一個函數,該函數返回 ai+1aiai+1−ai(

0iN10≤i≤N−1)中的最大值。

實現細節

本題只支持 C/C++/Pascal。

C/C++

你需要包含頭文件 gap.h。

你需要實現一個函數 findGap(T, N),該函數接受下面的參數,並返回一個 long long 類型的整數:

  • TT:子任務的編號(11 或者 22)
  • NN:序列的長度

你的函數 findGap 可以調用系統提供的查詢函數 MinMax(s, t, &mn, &mx),該函數的前兩個參數 ss 和 tt 是 long long 類型的整數,後兩個參數 &mn 和 &mx 是 long long

類型的整數的指針(mn 和 mx 是 long long 類型的整數)。當 MinMax(s, t, &mn, &mx) 返回時,變量 mn 將會存儲滿足 ai[s,t]ai∈[s,t] 中 aiai 的最小值,變量 mx 將會存儲滿足 ai[s,t]ai∈[s,t],aiai 的最大值。如果區間 [s,t][s,t] 中沒有序列中的數,則 mn 和 mx 都將存儲 1−1。在查詢時需要滿足 sts≤t,否則程序將會終止,該測試點計為 00 分。

Pascal

你需要使用單元 graderhelperlib。

你需要實現一個函數 findGap(T, N),該函數接受下面的參數,並返回一個 Int64 類型的整數:

  • TT:子任務的編號(11 或者 22)(Integer 類型)
  • NN:序列的長度(LongInt 類型)

你的函數 findGap 可以調用系統提供的查詢函數 MinMax(s, t, mn, mx),該函數的前兩個參數 ss 和 tt 是 Int64 類型的整數,後兩個參數 mn 和 mx 是傳引用方式的 Int64 類型的整數(過程內部對這兩個變量的修改會影響到外部的對應變量的值)。當 MinMax(s, t, mn, mx) 執行完畢時,變量 mn 將會存儲滿足 ai[s,t]ai∈[s,t] 中 aiai 的最小值,變量 mx 將會存儲滿足 ai[s,t]ai∈[s,t],aiai 的最大值。如果區間 [s,t][s,t] 中沒有序列中的數,則 mn 和 mx 都將存儲 1−1。在查詢時需要滿足 sts≤t,否則程序將會終止,該測試點計為 00 分。

樣例一

C/C++

考慮 N=4,a1=2,a2=3,a3=6,a4=8N=4,a1=2,a2=3,a3=6,a4=8。

則答案應該是 33,可以通過下面的幾組對 MinMax 的詢問獲得:

  • 調用 MinMax(1, 2, &mn, &mx),則 mn 和 mx 皆返回 22。
  • 調用 MinMax(3, 7, &mn, &mx),則 mn 返回 33,mx 返回 66。
  • 調用 MinMax(8, 9, &mn, &mx),則 mn 和 mx 皆返回 88。

Pascal

考慮 N=4,a1=2,a2=3,a3=6,a4=8N=4,a1=2,a2=3,a3=6,a4=8。

則答案應該是 33,可以通過下面的幾組對 MinMax 的詢問獲得:

  • 調用 MinMax(1, 2, mn, mx),則 mn 和 mx 皆返回 22。
  • 調用 MinMax(3, 7, mn, mx),則 mn 返回 33,mx 返回 66。
  • 調用 MinMax(8, 9, mn, mx),則 mn 和 mx 皆返回 88。

樣例評測方式

樣例測評系統從標準輸入中讀入兩行。第一行包含兩個整數,子任務編號 TT,和序列長度 NN。第二行包含 NN 個嚴格遞增的非負整數。然後該程序會向標準輸出中寫入兩行,第一行為 findGap 的返回值,第二行為花費 MM 的值。

下面的輸入描述了上面的樣例:

2 4
2 3 6 8

限制與約定

對於所有的測試點,有 2N1000002≤N≤100000。

每一個測試點開始測試之前,MM 都將被初始化為 00。

子任務 1(30 分):每一次調用 MinMax 都將使 MM 加 11。為了獲得所有分數,需要滿足對於該子任務下的所有測試點,都有 MN+12M≤N+12。

子任務 2(70 分):定義 kk 為調用 MinMax 時,區間 [s,t][s,t] 中的序列中數的數量。每次調用 MinMax,將使 MM 加上 k+1k+1。對於每一個測試點,如果 M3NM≤3N,你將得到 70 分,否則將得到 60M/N+1√160M/N+1−1 分。你的該子任務的得分是其下所有測試點中的最低分。

交互式類型的題目怎麽本地測試

時間限制:1s1s

空間限制:256MB256MB

下載

樣例及測評庫下載

題解

人生中第一道交互題

前30分很好拿 然而我交了好幾次才拿到......因為根本沒看清題

subtask 2 我覺得很有趣

首先把差的平均數算出來 然後答案肯定大於這個平均數

這樣就可以少管很多沒用的數了

誰搞的hack數據......卡掉了我3分...

#include "gap.h"
#include<cstdio>
#include<algorithm>
#define M 200005
using namespace std;
long long a[M];
long long findGap(int T, int N)
{
    long long ans=0,head,tail;
    MinMax(0,(long long)1e18,&head,&tail);
    if(T==1)
    {
        a[1]=head;a[N]=tail;
        for(int i=2,j=N-1;i<=j;i++,j--)
        {
            MinMax(head+1,tail-1,&head,&tail);
            a[i]=head;a[j]=tail;
        }
        for(int i=1;i<N;i++)ans=max(ans,a[i+1]-a[i]);
        return ans;
    }
    else
    if(N==2)return tail-head;
    else
    {
        int t=0;
        long long ave=(tail-head-1)/N+1,begin=head,end=tail;
        a[++t]=begin;
        for(long long i=begin;i<end;i+=ave)
        {
         //   if(i+1<=min(i+ave,end-1))
            MinMax(i+1,min(i+ave,end-1),&head,&tail);
         //   else continue;
            if(head==-1 && tail==-1)continue;
            a[++t]=head;a[++t]=tail;
        }
        a[++t]=end;
        for(int i=1;i<t;i++)ans=max(ans,a[i+1]-a[i]);
        return ans;
    }
    return 0;
}

交互感覺還是很有趣的一種題型

有趣不代表會做......

明天APIO rp++ (這麽晚了還不睡明天是要爆零了......)

UOJ #206. 【APIO2016】Gap