學長出題 比賽題解 17 10 18

2022-03-29 06:58:02 字數 4337 閱讀 8725

這次比賽由@falldream學長出題,歡迎去他的blog學習!

【t1】切課本

題意:

小 z 厭惡數學,他決定將數學課本切成一塊一塊的。他的課本是乙個 n*m 的矩形,小 z 決定切 k 刀,每刀他可以橫著切或者豎著切,但是切成的矩形的長和寬都必須是整數。當然,小 z 不會做出兩次相同的操作。例如 n=6,m=4,k=3 時,以下是一種合法的切法。

不巧的是,小 z 的數學老師知道了他這個行為,並且刁鑽的老師肯定會找到切出的矩形中面積最小的那一塊來 d 他, 所以小 z 想知道最優情況下面積最小的那一塊面積最大能是多少?

輸入:

輸入資料只包含一行三個整數 n,m,k,含義如題目所述。

輸出:

輸出乙個數字,表示答案。 如果沒有合法的方案,輸出-1。

題解:

固定乙個方向的刀數的時候,肯定是盡量平均切。

如果能只切一邊的話,只切一邊一定最優。

假設 n<=m, k>=m 時,考慮將一邊全部切開,剩下的平均切到另一邊。

長的邊切 m-1 刀,另一邊切 k-(m-1)刀一定最優,因為, n/(k-(n-1))>=m/(k-(m-1))。

1 #include2 #include3

using

namespace

std;

4 inline int

read()58

while(ch>='

0'&&ch<='9')

9return x*f;10}

11int n,m,k;long

long ans=0;12

intmain()

1323 printf("

%lld\n

",ans);

24return0;

25 }

【t2】海棠陣列題意:小 z 最喜歡陣列了,現在他得到了由 n 個正整數組成的陣列 ai。

他想構造乙個相同大小的正整數陣列 bi 滿足兩個陣列的差異度\(\sum_^|a_-b_|\)最小。

特殊的是, bi 陣列的所有元素必須滿足兩兩互質。

輸入:

第一行乙個數 n, 表示陣列大小。

接下來一行 n 個正整數 ai, 表示給定的陣列。(1<=ai<=30)

輸出:

輸出一行 n 個正整數 bi,表示答案。

輸出的數字必須滿足 1<=bi<=10^9。如果有多個答案,你可以輸出任意乙個。

題解:

ai<=30,那麼,如果選取的bi大於58,可以換成1,而答案不會更劣。

所以1<=bi<=58,再考慮互質的條件,說白了就是質因數不能重複,而58以內的質數只有16個,故使用狀壓dp。

用 f[i][j] 表示前 i 個數中,選取了集合 j 中的質數。用 fcts[i] 表示 i 的質因子集合。

有 f[i][j]=min( f[i-1][j\fcts[k]] + |ai-k| )。其中k取遍1到58。預處理出fcts加快速度。

1 #include2 #include3 #include4 #include5 #include6 #include

7#define ll long long

8#define mem(qaq,x) memset(qaq,x,sizeof(qaq))

9#define for(i,a,b) for (int i=a; i<=b; i++)

10#define ford(i,a,b) for (int i=a; i>=b; i--)

11#define file(fn) freopen(fn".in","r",stdin);freopen(fn".out","w",stdout);

12using

namespace

std;

1314

const

int fcts[59]=;

15int n,a[101],f[101][65536

];16

short g[101][65536],ans[101

];17

18 inline int abs(int x)

1920

void

init()

2425

void

dp()36}

37}38}

39}4041

intmain()

52 for(i,1,n) printf("

%d "

,ans[i]);

53return0;

54 }

【t3】修路題意:l 國包含 n 個城市和 m 條雙向道路,第 i 條道路連線 ui,vi 兩個城市, 距離為ti,這些道路將所有 n 個城市連線在一起。 明年, l 國將會在首都,也就是 1 號城市舉辦一年一度的 noi,所以 l 國的國王委託小 z 新建一些道路來減少一些城市到達首都的距離。小 z 很快修好了道路,但是他卻不是很滿意。他想知道最多可以少新建多少道路,滿足首都到所有城市的最短路長度和現在相同。

輸入:

第一行讀入三個數字 n,m,k,依次表示城市的數量,原有道路的數量和新建道路的數量。

接下來 m 行,每行三個數字 ui,vi,ti,表示一條原有的道路

最後 k 行,每行兩個數字 si,wi,表示一條新建的道路連線 1 和 si,距離為 wi。

輸出:

輸出乙個整數,表示最多能少修建多少條新建的道路 。

題解:

把所有新加的邊去個重,到相同的點的邊只保留乙個最小的,然後跑一次最短路。

一條新加的邊如果長度不是最短路一定可以去掉,否則只有滿足有其它最短路徑到達這個點的時候才

可以去掉。

算出到每個點最短路條數是否大等於 2 即可。

複雜度 o((n+k)logn)

1 #include2 #include3 #include4 #include5 #include6 #include

7 #include8

#define ll long long

9#define mem(qaq,x) memset(qaq,x,sizeof(qaq))

10#define for(i,a,b) for (int i=a; i<=b; i++)

11#define ford(i,a,b) for (int i=a; i>=b; i--)

12#define file(fn) freopen(fn".in","r",stdin);freopen(fn".out","w",stdout);

13using

namespace

std;

1415 inline int

in()

2223 typedef pairp;

2425

intn,m,k,ans;

26int h[50001],nxt[500001],to[500001],w[500001],tot=0

;27 inline void ins(int x,int y,int z)

28int dis[50001],num[50001

];29

int kkkk[50001

];30 priority_queue,greater>pq;

3132

void

init()

40 for(i,1

,k)45 for(i,1,n) if(kkkk[i]) ins(1,i,kkkk[i]), ins(i,1

,kkkk[i]);46}

4748

void

dij()

61else

if(dis[u.second]+w[i]==dis[to[i]])

62 num[to[i]]+=num[u.second];63}

64}65}

6667

intmain()

76 printf("%d"

,ans);

77return0;

78 }

數論出題組比賽用題 數列

思考難度 提高?難度 提高?演算法0 暴力 實際得分 0 演算法1 考慮x y 1x y 1x y 1的情況,顯然有an an 1 an 2a n a a an an 1 an 2 廢話 故 an an 1a n times a an an 1 an an an 1 a n times a n a ...

數論出題組比賽用題 傳球遊戲

思考難度 提高?難度 提高?正解 矩陣快速冪 若令f i j f i j 為第ii 次傳傳到第j j個人的方案數,易知f i j f i 1 j 1 f i 1 j 1 f i j f i 1 j 1 f i 1 j 1 但是直接這樣遞推o n m o nm 會t letl e,於是想到用矩陣來加速...

程式設計題 踢球比賽

時間限制 2秒 空間限制 65536k 有三隻球隊,每只球隊編號分別為球隊1,球隊2,球隊3,這三隻球隊一共需要進行 n 場比賽。現在已經踢完了k場比賽,每場比賽不能打平,踢贏一場比賽得一分,輸了不得分不減分。已知球隊1和球隊2的比分相差d1分,球隊2和球隊3的比分相差d2分,每場比賽可以任意選擇兩...