For the Honest Election
题目链接:L - For the Honest Election Gym - 100247L
题意
有n个人要投票选市长,P想当市长,所以他要找一些支持者给他投票,他可以把一群人分成若干人数相等的小组,对每个小组还可以执行类似的操作,投票规则是每个组分成的小组中有过半组投支持P这个组才支持P,问P通过适当的分组后让自己被选上市长需要的最少支持者
思路
第一种,利用递归的思想,将大的人数,不断划分成小的人数,因为这个很明显是需要利用乘法原理的,比如有十五个人,3 * 5和5 * 3结果是一样的,所以现在只需,不断将数据划分成各个质数即可。每个质数的对应数应该是n/2+1
第二种,则将第一种思想用筛法来进行实现,哎,这样需要考虑的情况过多,因为2非常特殊,每次在2的倍数,不是由2所对应的质数所组合而成,而是有4和8所组合而成,比较复杂,需特判。说明我对于2的特殊性,没有考虑周全。
代码
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef double db;
typedef long long ll;
const int MAXN = (int)1e6+7;
const int INF = (int)0x3f3f3f3f;
map<ll,ll> dp;
ll solve(ll N){
if (dp[N]!=0) return dp[N];
ll ans = N/2+1;
for (ll i = 2;i*i <= N;i ++){
if (N%i == 0) {
ans = min(ans,solve(N/i)*solve(i));
}
}
return dp[N] = ans;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int N;
dp[1] = 1;
cin >> N;
cout << solve(N) << endl;
}
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(ll i = (ll)j;i <= (ll)k;i ++)
#define per(i,j,k) for(ll i = (ll)j;i >= (ll)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef double db;
typedef long long ll;
const ll MAXN = (ll)3e6+7;
const ll INF = (ll)0x3f3f3f3f;
ll isNoPrim[MAXN];
ll N;
int main()
{
scanf("%lld",&N);
isNoPrim[1] = 1;
ll sr = (ll)sqrt(N);
rep(i,2,sr+1){
if (isNoPrim[i] != 1){
isNoPrim[i] = (i+1)/2;
if (i == 2) isNoPrim[i] = 2;
for (ll j = 2;j*i <= sr+1;j ++){
isNoPrim[i*j] = 1;
}
}
}
ll tmp = 0;
ll ans = 1;
while (N % 2 == 0){
tmp ++;
N /= 2;
}
while (tmp >= 7 ) tmp -= 3,ans *= 5;
if (tmp == 1) ans *= 2;
if (tmp == 2) ans *= 3;
if (tmp == 3) ans *= 5;
if (tmp == 4) ans *= 3*3;
if (tmp == 5) ans *= 3*5;
if (tmp == 6) ans *= 5*5;
rep(i,2,sr+1){
if (isNoPrim[i] > 1){
while(N%i==0) {
ans *= (ll)isNoPrim[i];
N /= i;
}
}
}
if (N > 1) ans *= (N+1)/2;
printf("%lld\n",ans);
}