這次比賽由@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【t2】海棠陣列題意:小 z 最喜歡陣列了,現在他得到了由 n 個正整數組成的陣列 ai。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 }
他想構造乙個相同大小的正整數陣列 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【t3】修路題意:l 國包含 n 個城市和 m 條雙向道路,第 i 條道路連線 ui,vi 兩個城市, 距離為ti,這些道路將所有 n 個城市連線在一起。 明年, l 國將會在首都,也就是 1 號城市舉辦一年一度的 noi,所以 l 國的國王委託小 z 新建一些道路來減少一些城市到達首都的距離。小 z 很快修好了道路,但是他卻不是很滿意。他想知道最多可以少新建多少道路,滿足首都到所有城市的最短路長度和現在相同。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 }
輸入:
第一行讀入三個數字 n,m,k,依次表示城市的數量,原有道路的數量和新建道路的數量。
接下來 m 行,每行三個數字 ui,vi,ti,表示一條原有的道路
最後 k 行,每行兩個數字 si,wi,表示一條新建的道路連線 1 和 si,距離為 wi。
輸出:
輸出乙個整數,表示最多能少修建多少條新建的道路 。
題解:
把所有新加的邊去個重,到相同的點的邊只保留乙個最小的,然後跑一次最短路。
一條新加的邊如果長度不是最短路一定可以去掉,否則只有滿足有其它最短路徑到達這個點的時候才
可以去掉。
算出到每個點最短路條數是否大等於 2 即可。
複雜度 o((n+k)logn)
1 #include2 #include3 #include4 #include5 #include6 #include7 #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分,每場比賽可以任意選擇兩...