程式設計思維與實踐 Week4 作業

2021-10-04 02:38:34 字數 4083 閱讀 6527

a - ddl 的恐懼

zjm 有 n 個作業,每個作業都有自己的 ddl,如果 zjm 沒有在 ddl 前做完這個作業,那麼老師會扣掉這個作業的全部平時分。

所以 zjm 想知道如何安排做作業的順序,才能盡可能少扣一點分。

請你幫幫他吧!

input

輸入包含t個測試用例。輸入的第一行是單個整數t,為測試用例的數量。

每個測試用例以乙個正整數n開頭(1<=n<=1000),表示作業的數量。

然後兩行。第一行包含n個整數,表示ddl,下一行包含n個整數,表示扣的分。

output

對於每個測試用例,您應該輸出最小的總降低分數,每個測試用例一行。

sample input

33 3 3

10 5 1

1 3 1

6 2 3

1 4 6 4 2 4 3

3 2 1 7 6 5 4

sample output05

hint

上方有三組樣例。

對於第一組樣例,有三個作業它們的ddl均為第三天,zjm每天做乙個正好在ddl前全部做完,所以沒有扣分,輸出0。

對於第二組樣例,有三個作業,它們的ddl分別為第一天,第三天、第一天。zjm在第一天做了第乙個作業,第二天做了第二個作業,共扣了3分,輸出3。

*解題思路

首先根據每道題扣的分值按從大到小排好序。為了盡量少的影響其他作業。所以我們將分值最大的作業安排在它的截止日期做。剩下的依次類推,都從它的截止日期往前找。如果沒有時間,就把它加到丟失總分中。

#include

#include

#include

using

namespace std;

struct work

w[1020];

bool

cmp(work& a,work& b)

int day[

1020];

intmain()

}if(!flag)

sum+

=w[i]

.loss;

}printf

("%d\n"

,sum);}

return0;

}

b - 四個數列

zjm 有四個數列 a,b,c,d,每個數列都有 n 個數字。zjm 從每個數列中各取出乙個數,他想知道有多少種方案使得 4 個數的和為 0。

當乙個數列中有多個相同的數字的時候,把它們當做不同的數對待。

請你幫幫他吧!

input

第一行:n(代表數列中數字的個數) (1≤n≤4000)

接下來的 n 行中,第 i 行有四個數字,分別表示數列 a,b,c,d 中的第 i 個數字(數字不超過 2 的 28 次方)

output

輸出不同組合的個數。

sample input

6-45 22 42 -16

-41 -27 56 30

-36 53 -37 77

-36 30 -75 -46

26 -38 -10 62

-32 -54 -6 45

sample output

5hint

樣例解釋: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

解題思路

如果對四個數列分別列舉,複雜度為o(n^4).將a,b陣列相加然後排序,o(

n2logn).再將c,d陣列相加的所有情況進行列舉,o(n2).再對列舉出的每乙個值在第乙個排序過的陣列中進行二分搜尋,o(logn)。

注意這裡可以使用upper_bound和lower_bound。

在從小到大的排序陣列中,lower_bound( begin,end,num):從陣列的begin位置到end-1位置二分查詢第乙個大於或等於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。upper_bound( begin,end,num):從陣列的begin位置到end-1位置二分查詢第乙個大於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。

#include

#include

using

namespace std;

int a[

4020

],b[

4020

],c[

4020

],d[

4020];

int sum1[

4020

*4020

],sum2[

4020

*4020];

int n,num1,num2;

intmain()

printf

("%d\n"

,sum);}

return0;

}

c - tt 的神秘禮物

tt 是一位重度愛貓人士,每日沉溺於 b 站上的貓咪頻道。

有一天,tt 的好友 zjm 決定交給 tt 乙個難題,如果 tt 能夠解決這個難題,zjm 就會買乙隻可愛貓咪送給 tt。

任務內容是,給定乙個 n 個數的陣列 cat[i],並用這個陣列生成乙個新陣列 ans[i]。新陣列定義為對於任意的 i, j 且 i != j,均有 ans = abs(cat[i] - cat[j]),1 <= i < j <= n。試求出這個新陣列的中位數,中位數即為排序之後 (len+1)/2 位置對應的數字,』/』 為下取整。

tt 非常想得到那只可愛的貓咪,你能幫幫他嗎?

input

多組輸入,每次輸入乙個 n,表示有 n 個數,之後輸入乙個長度為 n 的序列 cat, cat[i] <= 1e9 , 3 <= n <= 1e5

output

輸出新陣列 ans 的中位數

sample input

41 3 2 4

31 10 2

sample output18

解題思路

給出數列後,答案的範圍是已知的,絕對值最小不會小於0,而最大值就是排序後的數列 a[n-1] - a[0]。

如果給定乙個數p,如何判斷它是不是中位數?

計算p在數列中的名次即可。

•如果p從小到大排的名次比中位數小,說明什麼? p比中位數要小

•如果p從小到大排的名次比中位數大,說明什麼? p比中位數要大

•如果p從小到大排的名次等於中位數,說明什麼? p就是中位數

結論:滿足單調性,可以二分p!

計算p的名次:

將x從小到大排列可以去絕對值。 那麼計算xj - xi <= p的二元組對數即可。

移項可得 xj <= xi + p, 列舉下標i然後計算滿足條件的下標j的個數 也可以二分!

這裡使用lower_bound( ) 函式查詢第乙個大於或等於 xi +p的數字,找到返回該數字的位址。

#include

#include

#include

using

namespace std;

intmain()

if(rank<=

(n*(n-1)

/2-mid)

) r=p;

else l=p+1;

} cout<1<}return0;

}

程式設計思維與實踐 Week4作業

題目 zjm 有 n 個作業,每個作業都有自己的 ddl,如果 zjm 沒有在 ddl 前做完這個作業,那麼老師會扣掉這個作業的全部平時分。所以 zjm 想知道如何安排做作業的順序,才能盡可能少扣一點分。請你幫幫他吧!input 輸入包含t個測試用例。輸入的第一行是單個整數t,為測試用例的數量。每個...

程式設計思維與實踐 Week4 作業

zjm 有 n 個作業,每個作業都有自己的 ddl,如果 zjm 沒有在 ddl 前做完這個作業,那麼老師會扣掉這個作業的全部平時分。所以 zjm 想知道如何安排做作業的順序,才能盡可能少扣一點分。請你幫幫他吧!input 輸入包含t個測試用例。輸入的第一行是單個整數t,為測試用例的數量。每個測試用...

《程式設計思維與實踐》week4 作業題

zjm 有 n 個作業,每個作業都有自己的 ddl,如果 zjm 沒有在 ddl 前做完這個作業,那麼老師會扣掉這個作業的全部平時分。所以 zjm 想知道如何安排做作業的順序,才能盡可能少扣一點分。請你幫幫他吧!輸入包含t個測試用例。輸入的第一行是單個整數t,為測試用例的數量。每個測試用例以乙個正整...