【UVa 10780】 Again Prime? No time.

本文介绍了一种算法,用于解决给定两个正整数N和M时,找到最大的正整数k,使得Mk能整除N的阶乘。通过质因子分解并比较指数来确定k的值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目大意】

给定两个正整数N,M。求一个最大的正整数k,使得Mk|N!


【分析】

直接将N!和M的质因子分解,然后比较指数即可。

N!的质因子分解式:

    设N!=p1a× p2a× p3a3 ××× pkak

那么pi的指数 ai=sigma(N/(pij))  pij<=N


【代码】

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,b,a) for(int i=(b);i>=(a);--i)
#define pf printf
#define sf scanf
#define p_b push_back
#define INF (~0U>>1)
#define MAXN 20010

string error("Impossible to divide");
int N,M;
bool f[MAXN+10];
int zs[MAXN+10];
vector <int> Prime;

void Getprime(){
	int n=sqrt(MAXN);
	rep(i,2,MAXN){
		if(!f[i]){
			Prime.p_b(i);
			for(int j=i*i;j<=MAXN;j+=i)
			    f[j]=true;
		}
	}
}

int Getans(){
	int rt=INF;
	memset(zs,0,sizeof zs);
	int n=Prime.size();
	int m;
	rep(i,0,n-1){
		if(Prime[i]>N){
			m=i;
		    break;
	    }
		int acc=0,tmp=Prime[i];
		while(tmp<=N){
			acc+=N/tmp;
			tmp*=Prime[i];
		}
		zs[i]=acc;
	}
	rep(i,0,m-1){
		if(M%Prime[i]!=0) continue;
		int acc=0;
		while(M%Prime[i]==0){
			acc++;
			M/=Prime[i];
		}
		rt=min(rt,zs[i]/acc);
	}
	return M==1?rt:0;
}

int main(){
	int Kase;
	sf("%d",&Kase);
	Getprime();
	rep(i,1,Kase){
		pf("Case %d:\n",i);
		sf("%d%d",&M,&N);
		int ans=Getans();
		if(ans)
		    pf("%d\n",ans);
		else
		    cout<<error<<endl;
	}
	return 0;
}


UVA11076 Add Again问题的大意如下: 给定一组整数,其中可能包含重复的数字。需要将这些数字的所有不同排列组合中的每一个数值相加,然后计算这个总和。 要解决此类问题,可以通过以下方法进行分析与实现: - 首先统计每个数字出现的次数,利用组合数学的知识来避免生成所有排列。 - 对于每一位(个位、十位、百位等),计算该位上每个数字对总和的贡献。具体来说,如果共有 $k$ 个不同的排列,那么每个数字在每一位上出现的次数为 $k / n$,其中 $n$ 是数字的总数。 - 每一位的总贡献等于该位上所有数字的值乘以其出现次数之和,再乘以对应的位置权值(如个位是1,十位是10,百位是100等)。 例如,对于输入数据组 `[1, 2, 3]`: - 所有不同的排列是:[123, 132, 213, 231, 312, 321]。 - 总和为 `123 + 132 + 213 + 231 + 312 + 321 = 1332`。 具体的实现代码如下: ```python from math import factorial from collections import Counter def solve(): numbers = list(map(int, input().split())) count = len(numbers) # 统计每个数字的出现次数 freq = Counter(numbers) # 计算所有排列的数量 total_permutations = factorial(count) for v in freq.values(): total_permutations //= factorial(v) # 计算每个位置的贡献 sum_of_digits = sum(numbers) contribution_per_digit = total_permutations // count # 计算最终结果 result = 0 position_value = 1 for _ in range(count): digit_sum = sum_of_digits * contribution_per_digit result += digit_sum * position_value position_value *= 10 print(result) # 调用solve函数运行逻辑 solve() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值