1. 程式人生 > >[UOJ282]長度測量雞

[UOJ282]長度測量雞

als -128 minus 2.7 方案 不存在 mathjax lns sim

思路:

數學歸納。

設最少所需刻度數為$s$,則$n和s$的關系為:

$n=1,s=0;$

$n=2,s=1;$

$n=3,s=3;$

...

觀察發現$s=n(n-1)/2$,得到$sn$時,滿足條件。

然而只有50分。。

因為我手算錯了,$n=3,s=2$。

然而人不能沒有信仰,就把$<$改成$\leq$,A了。。

正解:

當$n>3$時,一定不能滿足條件。

附官方題解:

from nneztlk

算法一

直接枚舉刻度, 時間復雜度為 O((n(n+1)/21n1))O((n(n+1)/2−1n−1)).

n=5n=5 時這個數是 (144)=1001(144)=1001, n=8n=8 時這個數是 (357)=6724520(357)=6724520. 期望得分 102010∼20 分.

算法二

我們需要題目描述中的 sjsi (0i<jn)sj−si (0≤i<j≤n) 這 n(n+1)2n(n+1)2 個數取到 1n(n+1)21∼n(n+1)2 的所有整數, 所以每個整數只能取一次, 即每種長度只能被一種方法量出. 特別地, sisi1(1in)si−si−1(1≤i≤n) 這

nn 段長度兩兩不同, 故只能是 1,2,,n1,2,…,n 的一種排列.

枚舉排列, 時間復雜度為 O(n!)O(n!). n=8n=8 時這個數是 4032040320. 期望得分 2020 分.

算法三

事實上, n=1,2,3n=1,2,3 時可以直接試出刻度方案, 分別為 ,{1},{1,4}∅,{1},{1,4}, 而對所有 n>3n>3 都不存在滿足要求的刻度. 證明如下:

M=n(n+1)2M=n(n+1)2, 則對 n>3n>3, M10M≥10. 現假設存在滿足要求的刻度方案. 由於需要量出

M1M−1 的長度, 所以 11 或 M1M−1 處必須有刻度, 由對稱性不妨設 11 處有. 要量出 M2M−2 的長度, 2,M2,M12,M−2,M−1 中需要有一處有刻度, 而如果 22 或 M1M−1 處有刻度, 則可以用兩種方法量出長度 11, 矛盾! 所以 M2M−2 處必須有刻度. 此時由 (M2)1=M3(M−2)−1=M−3, M3M−3 的長度已經可以被量出. 要量出 M4M−4 的長度, 2,4,M3,M42,4,M−3,M−4 四處必有一處有刻度. 容易發現只有 44 處的刻度不會引起重復.

現在已經知道 1,4,M21,4,M−2 處都需要有刻度, 而長度 M5M−5 尚未被量出. 欲量出 M5M−5, 需要 3,5,M5,M4,M13,5,M−5,M−4,M−1 中的一處有刻度. 然而它們都會導致 1,2,31,2,3 中的某個長度能被兩種方法量出, 矛盾! 故不存在滿足要求的刻度.

所以只需判斷 nn 是否大於 33. 時間復雜度 O(1)O(1), 期望得分 100100 分.

我的AC代碼:

 1 #include<cstdio>
 2 int main() {
 3     int t;
 4     scanf("%d",&t);
 5     while(t--) {
 6         int n;
 7         scanf("%d",&n);
 8         printf("%d\n",((n*(n+1)>>2)<=n)?1:-1);
 9     }
10     return 0;
11 }

附最短代碼(Python2.7):

1 print\n.join([-1if input()>3 else1for i in range(input())])

[UOJ282]長度測量雞