QUST程式設計賽G題 佔教室

2021-06-26 18:27:37 字數 2902 閱讀 4776

在青科大,經常有活動需要占用教室。。。。比如開班會。。比如辦活動。。比如學長講課。。。。。。。反正很多事啦。。。。於是。。。新一輪搶占教室開始了。。此前經常會有人占用教室時發生衝突(沒有教室可佔或者佔不夠需要的教室t t),為了社會的和諧我們決定成立協調委員會來協調教室幫助需要教室確無法滿足的同學,我們有接下來n天的借教室資訊,其中第i天學校有ri個教室可供租借。共有m組同學需要借用教室,每組用三個正整數描述,分別為dj,sj,tj,表示某租借者需要從第sj天到第tj天租 借教室(包括第sj天和第tj天),每天需要租借dj個教室。我們假定,租借的同學對教室的大小、地點沒有要求。只需要滿足每天dj個教室的**即可,而它們具體是哪些教室,每天是否是相同的教室則沒有意見。

借教室的原則自然是先到先得,(這m組人的排列次序就是來佔教室的先後次序,先到的會在黑板上寫上如「某某日至某某日占用教室。。請勿重占。。謝謝。。」等字樣來確保占用的教室在需要的時候可用以保證自己活動的順利進行。。。,如果時間不衝突的話教室可以共享(如編號1~k天a組占用,k+1~n天b組占用不會引起衝突)如果遇到一組人需要教室而無法完全滿足,此時就是協調委員會派上用場的時候啦~這組人會跑去協調委員會尋求幫助。這裡的無法滿足指從

第sj天到第tj天中有至少一天剩餘的教室數量不足dj個。 現在我們需要知道,是否會有人需要教室而無法完全滿足。是哪一組去協調委員會尋求幫助。 

第一行有乙個整數t表示測試資料的組數

第二行包含兩個正整數n,m,表示天數和需要教室的同學的組數。 第三行包含n個正整數,其中第i個數為ri,表示第i天可用於租借的教室數量。 接下來有m行,每行包含三個正整數dj,sj,tj,表示租借的數量,占用開始、結束分別在第幾天。 每行相鄰的兩個數之間均用乙個空格隔開。天數與同學均用從1開始的整數編號。

資料範圍:1 ≤ n,m ≤ 10^6,0 ≤ri,dj ≤ 10^9,1 ≤ sj ≤ tj ≤ n。

有t組,每一組資料都以」case #t:」t為當前資料組數(注全為半形符號)作為第一行接下來如果所有訂單均可滿足,則接下來的輸出只有一行,包含乙個整數 0。否則(訂單無法完全滿足) 接下來輸出兩行,第二行輸出乙個負整數-1,第三行輸出需要幫助的同學的編號。 

14 3

2 5 4 3

2 1 3

3 2 4

4 2 4

case #1:
-1

2  第 1 組同學滿足後,4 天剩餘的教室數分別為 0,3,2,3。第 2 組同學要求第 2 天到 第 4 天每天提供 3 個教室,而第 3 天剩餘的教室數為 2,因此無法滿足。分配停止,第二組同學會去委員會尋求幫助。

看到題目的第一反應是模擬,隊友的想法和我一樣,於是很乾脆的敲了乙個模擬,結果自然而然的——沒過……

這道題不能簡單的使用模擬法做,因為資料太大會超時。

借教室的原則是先到先得,也就是說我們要按照訂單的先後順序依次為每份訂單分配教室(這句話很重要,這決定了分配是按照順序的)。如果在分配的過程中遇到乙份訂單無法完全滿足,則需要停止教室的分配,通知當前申請人修改訂單。這裡的無法滿足指從第sj天到第tj天中有至少一天剩餘的教室數量不足dj個。

現在我們需要知道,是否會有訂單無法完全滿足。如果有,需要通知哪乙個申請人修改訂單。

二分法**如下:

#include#includeint r1[1000010],sum[1000010],d[1000010],s[1000010],t[1000010];

int main()

for(i=1;i<=m;i++)

l=1;

r=m+1; //二分終點要注意,如果最後終點不變,直到m+1才不合格,那麼借用要求全部滿足;如果r改變了,那麼要求不滿足

now=0;//如果可行一定是連續的訂單,所以可用二分 now指的是上乙個mid,為了恢復sum陣列 do}

else

}now=mid;

flag=1;

s1=0;

for(i=1;i<=n;i++)//sum按照天數計

}if(flag==1)

else

r=mid;

} while(l!=r);

if(flag==1&&l==m+1)

else

}return 0;

}

另外山科大隊用線段樹解的,分析一下複雜度也是在可以接受的範圍內的,線段樹法**如下:

#include #include #include #include using namespace std;  

const int maxn = 1000000+10;

int a[maxn];

int n,m,s,t,need;

struct node

int mid = (l+r) / 2;

build(a,l,mid,p+p);

build(a,mid+1,r,p+p+1);

min[p] = min(min[p+p],min[p+p+1]);

} void update(int p )

void push(int p)

void getdec(int l ,int r,int p, int a,int b,int need)

push(p);

int mid = (l+r) / 2;

if (b <= mid ) getdec(l,mid,p+p,a,b,need); else

if (a > mid ) getdec(mid+1,r,p+p+1,a,b,need); else

update(p);

} }tree;

int main()

} cout << 0 << endl;

return 0;

}

*注:本題改編自noip2012提高組  借教室

QUST程式設計賽C題 數字LED

題目描述 讓我們研究一下下面的數字led顯示屏 通常他可以顯示0 9之間的任意乙個數,但是付付最近發現了他的乙個新用處!他可以只用1塊led版顯示11這個數字,如下圖 現在給你乙個整數,你能計算出他至少需要多少led塊顯示嗎?輸入 輸入包含多組測試資料。第一行有乙個整數t,代表資料組數。對於每組測試...

xdoj1269 2017新生賽現場賽G題

時間限制 1 sec 記憶體限制 128 mb 提交 39 解決 12 提交 狀態 討論版 williamchen 每天就知道玩遊戲,他最喜歡玩 the binding of issac。有時候他會進入乙個充滿石頭的房間,有時候他需要控制以撒從這個房間的某個位置走到另乙個位置。為了簡化問題,乙個房間...

程式設計競賽 G 題 逃離迷宮

思路 一開始從起點開始bfs搜,每搜到一把鑰匙對應的k i j 的值更新為起點到該鑰匙的距離,沒有搜到的鑰匙則為初始值 1。然後再從終點開始一次bfs,搜到一把鑰匙之後,先判斷k i j 是否為 1,是的話說明無法從起點走到該鑰匙位置,即通過這把鑰匙從起點到終點是不可行的,那麼繼續向該位置的4個方向...