麓麓學數學(math.cpp)
描述
麓麓不僅玩遊戲十分厲害,而且數學也非常好,可是這次他被
一道數學題難住了,於是他來求助身為資訊大佬的你來解決這個問
題:對於乙個正整數 n,從 1!、2!、3!、......、n!中至少刪去幾個
階乘,就能使餘下的階乘的乘積是完全平方數?
格式
輸入格式
僅一行,包含乙個整數 n(1≤n≤500)。
輸出格式
第一行包含乙個整數 k,表示最少需要刪去的階乘個數。
接下來一行,從小到大排列的 k 個[1,n]之間的整數,給出刪數的
方案。注意若方案不止一種,輸出方案從小到大排序序列最小一
組即可。
樣例 1
樣例輸入 1
5樣例輸出 1
22 5
限制
各個測試點 1s
對於 100%資料 1≤n≤500
提示樣例說明:去掉 2!和 5!,剩下的 4,3,1 的階乘乘積為 4!×3!×
1!=144=12^2。
沒啥提示,這題考數學。
solution:
本題考察數學+暴力巧解。
首先很容易想到暴力搜尋,直接迭代加深搜尋ida*(運氣好的話限制深度可以過),但實際上這題如果我們提前預知結論:答案個數不超過3。這樣就好做了,考慮對於乙個數k,它是不是完全平方數,即它的質因子的個數是否都為偶數。(譬如4,它的質因子只有2且2的個數為偶數,則4是完全平方數)。
那麼提前預處理,直接把每個數表示為它的質因子以及每個質因子的個數,這樣就可以方便地判斷除法之後是否為完全平方數了。
進一步,我們可以直接把每個質因子個數表示為「奇偶」,因為我們並不需要質因子的個數,只需要其奇偶性。(壓位用,譬如:某一質因數個數奇+奇=偶,偶+偶=奇,偶+奇=奇)
親測,其實完全不壓位也能過,但是那樣**太短難度直線下降。
證明讓520口述。
如果你數學炸天(譬如高一數竟班的雞哥,他告訴我的結論在vijos上有50分)
詳解見**
**:
1/*這題只要知道結論:答案個數小於等於3個。就so easy了,方法很多,可以亂寫,我寫的狀壓僅供參考——by 520
*/2 #include3
#define n 501
4 typedef long
long
ll;5
int n,tot,pri[100];6
bool
b[n];
7 ll m,mask[n][2
],aim0,aim1;
8int
main()
926 m=1;27
for(int j=50;j1) /*
這裡的意思同上,只不過兩部分都用了m,而m<<1的值只能表示
28乙個質數,所以將兩部分隔開,這裡就是mask[i][1]啦
*/29
while(k%pri[j]==0
)33 mask[i][0]^=mask[i-1][0]; /*
這裡就是合併該數和上乙個數的質因子個數
*/34 mask[i][1]^=mask[i-1][1
];35
} 36
37if(mask[n][0]==0&&mask[n][1]==0) /*
若n的質因子個數為偶數,則不需刪除任何數
*/38
4243
//上面預處理後,下面直接依次列舉刪去1個、2個、3個的情況就ok了
4445
for(int i=2;i<=n;i++)aim0^=mask[i][0],aim1^=mask[i][1]; /*
這裡是刪去1個的暴力列舉,
46aim0取出前面50個質因數的壓位值,aim1後面的同理
*/47
for(int i=2;i<=n;i++)
48if(mask[i][0]==aim0&&mask[i][1]==aim1) /*
上面aim0異或出的值即若和mask[i][0]相等,
49且aim1和後面的相等,則說明刪去該數就保證質因子個數為偶數
*/50
5556
for(int i=2;i/*
刪去2個數的列舉,直接n方暴力
*/57
for(int j=i+1;j<=n;j++)
58if(aim0==(mask[i][0]^mask[j][0])&&aim1==(mask[i][1]^mask[j][1])) //
思路和列舉1個的一樣
5964
65for(int i=2;i1;i++) //
刪去3個數的列舉,n^3暴力,實際是不會超時的,因為最壞情況難以出現
66for(int j=i+1;j)
67for(int k=j+1;k<=n;k++)
68if(aim0==(mask[i][0]^mask[j][0]^mask[k][0])&&aim1==(mask[i][1]^mask[j][1]^mask[k][1
]))69
74 }
遊記 準信心賽
真的,只有幾句話。別看了。前兩題都是水題,人均 100 10010 0 但是容不容易打掛?容易。尤其是 t1t1 t1。我打完之後,估摸著,前兩題要是爆了,這場就算白打了。特別我看了看 t3t3 t3不是很會。然後做了個明智的決定 寫對拍。然後 t1t1 t1真的就拍出來了。為啥我想拍 t1t1 t...
20191016信心賽題解
題目鏈結 真就按照題意暴力模擬就行。沒別的方法。題目鏈結 題意就是給一棵以1為根的有根樹,求最少改變多少條邊使得1到每個點的路徑都滿足安全邊數量不少於危險邊。顯然更改時貪心的想一定是盡量在深度較小處更新。為了統計結果,設陣列a i 表示從1到i路徑上安全邊與危險邊的差值。顯然當a i 0時這一點不合...
NOIP2018 信心賽 雞腿
波波手上有許多校慶時分發的雞腿券,他決定用玩遊戲的方式來分配這些雞腿券。已知波波會給出乙個 的 棋盤,並且他會在棋盤的左上角 1,1 處放置乙個棋子。兩名雞腿競爭者 和 將輪流移動棋子,每一回合 選手只能向上 下 左 右四個方向使棋子移動一步。為了使遊戲盡快結束波波還規定不能重複經過已經經過的格 子...