[題解]TopCoder SRM 617 div2 T3 MyVeryLongCake
題目描述
你有一個很薄的蛋糕。為簡單起見,我們可以認為蛋糕是一維的。蛋糕的長度是n。你正在等一些朋友。在朋友到達之前,你要把蛋糕切成多塊,以便當朋友們到達時,你可以用以下方法將蛋糕分給他們:從蛋糕的開頭開始,首先,你將給你的第一個朋友連續的一部分,然後連續給你的第二個朋友,以此類推。當然,你想要公平。也就是說,你的每個朋友都應該收到相同的蛋糕總量。 (對於不同的朋友,件數可能不同,但他們的長度總和必須相同。)如上所述,你想在朋友到達之前切蛋糕。但是,你不知道會有多少朋友來。你只知道朋友的數量將是小於n的n的因子。你得到了int n。你想要以這樣的方式切蛋糕:對於每個有效數量的朋友,當使用上述方法時,可以給每個朋友提供相同數量的蛋糕。並且把蛋糕分成儘可能少的部分。
題意概述
把一個長度為n(2<=n<=10^9)的區間分成儘可能少的部分,使得對於n的每一個小於n的因子k,可以把區間分成k個連續的部分並且每一部分數值之和相同。輸出最少要分成多少部分。
樣例
Input 1
6
Output 1
4
解釋:分為2 1 1 2
- 如果有1個朋友,把所有的都給他
- 如果有2個朋友,把前兩份給第一個 後兩份給第二個
- 如果有3個朋友,把2給第一個 1 1給第二個 2給第3個
Input 2
3
Output 2
1
解釋:不用切,只可能有1個朋友
Input 3
15
Output 3
7
解釋:分為 3 2 1 3 1 2 3
- 如果有三個朋友 3 2|1 3 1|2 3
- 如果有五個朋友 3|2 1|3|1 2|3
Input 4
1000000000
Output 4
600000000
Input 5
577007436
Output 5
384671628
分析
搞了半天最後才發現原來是個尤拉函式TAT。
把蛋糕看成一個n*1的矩形
設a * b=n,那麼,對於每一個i(1<=i < b),第a * i個方格後面會被切一刀,也就是說,對於每一個k(1<=k< n),如果k和n不互質,第k個方格後面要被切一刀。
由於n以內(不包括n)的數中與n互質的數有
程式碼
//tc is healthy, just do it
#include <bits/stdc++.h>
using namespace std;
class MyVeryLongCake {
public:
int cut( int n );
};
int euler(int x){
int ans=x;
for(int i=2;i*i<=x;i++){
if(x%i==0){
ans-=ans/i;
while(x%i==0)x/=i;
}
}
if(x>1)ans-=ans/x;
return ans;
}
int MyVeryLongCake::cut(int n) {
return n-euler(n);
}