B. Math

time limit per test:1 second
memory limit per test:256 megabytes

Description:

JATC's math teacher always gives the class some interesting math problems so that they don't get bored. Today the problem is as follows. Given an integer n, you can perform the following operations zero or more times:

  • mul x: multiplies n by x (where x is an arbitrary positive integer).
  • sqrt: replaces nn with n−−√n (to apply this operation, n−−√n must be an integer).

You can perform these operations as many times as you like. What is the minimum value of n, that can be achieved and what is the minimum number of operations, to achieve that minimum value?

Apparently, no one in the class knows the answer to this problem, maybe you can help them?

Input:

The only line of the input contains a single integer nn (1≤n≤10^6,1≤n≤10^6) — the initial number.

Output:

Print two integers: the minimum integer n that can be achieved using the described operations and the minimum number of operations required.

Sample Input:

20

Sample Output:

10 2

题意:

对n可以进行开方以及乘以一个数这两种操作(无限次),求经过操作后最小的为多少。

题解:

唯一分解定理告诉我们,n可以分解成若干个质数的乘积,比如n=a1^p1*a2^p2*...*an^pn,其中a1,a2,.....,an为质数。

由于可以乘以一个任意的数,所以我们是可以改变p1,p2..pn的值的。我们假定现在已经把指数变为可多次开方的形式,那么最小的n值就是a1*a2*...*an。

现在主要问题是解决操作次数,我们设一个数t,t为2^t>=max(p1,p2,....,pn)的最小值,那么现在我们就可以进行t次开方。

最后再判断一下乘法操作就可以了。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std; typedef long long LL ;
const int N = 1e6+;
int tot,n;
int u[N],prim[N],vis[N],a[N]; int main(){
scanf("%d",&n);
for(int i=;i<=sqrt(n);i++){
for(int j=i*i;j<=n;j+=i){
if(!vis[j]) vis[j]=;
}
}
for(int i=;i<=n;i++) if(!vis[i]) prim[++tot]=i;
int tmp = n,cnt=;
while(tmp>){
if(tmp%prim[cnt]==){
tmp/=prim[cnt];
a[prim[cnt]]++;
}else{
cnt++;
}
}
int maxn = ;
cnt=;
LL ans = ,f = ;
bool flag=false;
for(int i=;i<=n;i++) if(a[i]){
maxn=max(maxn,a[i]),ans*=i;
}
for(int i=;i<=n;i++){
if(a[i]&&a[i]!=maxn) flag=true ;
}
while(){
if(f>=maxn){
if(flag) break ;
if(f==maxn) flag=false;else flag=true;
break;
}
f*=;
cnt++;
}
printf("%lld %d",ans,cnt+(flag==true));
return ;
}

后来我看了一下其它人的代码,十分简洁,发现不用把素数给筛出来,具体代码可以看下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std; int n,cnt,ans=;
vector <int > vec ; int main(){
scanf("%d",&n);
int maxn = ;
for(int i=;i<=n;i++){
cnt = ;
if(n%i==) ans*=i;
while(n%i==){
n/=i;
cnt++;
}
while(<<(maxn)<cnt) maxn++;
if(cnt) vec.push_back(cnt);
}
int flag = ;
for(int i=;i<vec.size();i++){
if(vec[i]!=(<<maxn)) flag=;
}
printf("%d %d",ans,flag+maxn);
return ;
}

Codeforces Round #520 (Div. 2) B. Math的更多相关文章

  1. Codeforces Round #520 (Div. 2) B. Math 唯一分解定理+贪心

    题意:给出一个x 可以做两种操作  ①sqrt(x)  注意必须是完全平方数  ② x*=k  (k为任意数)  问能达到的最小的x是多少 思路: 由题意以及 操作  应该联想到唯一分解定理   经过 ...

  2. Codeforces Round #520 (Div. 2) B math(素数因子的应用)

    题意: 给出一个n ; 有两个操作: 1,mul A   ,   n=n*A   : 2,sqrt()  ,  n=sqrt(n)  开更出来必须是整数 : 求出经过这些操作后得出的最小  n , 和 ...

  3. Codeforces Round #520 (Div. 2)

    Codeforces Round #520 (Div. 2) https://codeforces.com/contest/1062 A #include<bits/stdc++.h> u ...

  4. CF每日一练 Codeforces Round #520 (Div. 2)

    比赛过程总结:过程中有事就玩手机了,后面打的状态不是很好,A题理解错题意,表明了内心不在状态,B题想法和思路都是完全正确的,但是并没有写出来,因为自己代码能力不强,思路不是特别清晰,把代码后面写乱了, ...

  5. Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)

    https://codeforces.com/contest/1062/problem/E 题意 给一颗树n,然后q个询问,询问编号l~r的点,假设可以删除一个点,使得他们的最近公共祖先深度最大.每次 ...

  6. Codeforces Round #520 (Div. 2) Solution

    A. A Prank Solved. 题意: 给出一串数字,每个数字的范围是$[1, 1000]$,并且这个序列是递增的,求最多擦除掉多少个数字,使得别人一看就知道缺的数字是什么. 思路: 显然,如果 ...

  7. Codeforces Round #520 (Div. 2) D. Fun with Integers

    D. Fun with Integers 题目链接:https://codeforc.es/contest/1062/problem/D 题意: 给定一个n,对于任意2<=|a|,|b|< ...

  8. Codeforces Round #520 (Div. 2) C. Banh-mi

    C. Banh-mi time limit per test:1 second memory limit per test:256 megabytes 题目链接:https://codeforc.es ...

  9. Codeforces Round #520 (Div. 2) A. A Prank

    A. A Prank time limit per test   1 second memory limit per test    256 megabytes 题目链接:https://codefo ...

随机推荐

  1. python-映射·字典

    1.创建字典:字典由键值对组成,每个键值对就是字典的一个元素,键值对之间用分号(:)隔开,元素之间用逗号(,)隔开.字典中的键必须是唯一 且不可变得(不可以是列表或者字典).字典中的元素是无序的. d ...

  2. php复制目录很浪

    一不小心搞出个超级深层次文件夹 主要是因为懒,在网上随便找了段复制文件夹的代码贴上了,结果是很恐怖,一个文件夹复制到他自身里面的时候,将会产生循环嵌套文件夹,后果是,windows因为文件名太长而无法 ...

  3. MVC中Session的使用和传递

    1.登录时在controller中记录session,代码如下: public ActionResult Login(UserLoginViewModel uViewModel) { if (Mode ...

  4. 深度学习(deep learning)优化调参细节(trick)

    https://blog.csdn.net/h4565445654/article/details/70477979

  5. OrCAD生成网表

    1. 先选中.dsn设计文件 2. 按照默认设置,点击OK即可生成网表

  6. SharedPreferences Android

    类似iOS的NSUserDefaults,采用key-value(键值对)形式,主要用于轻量级的数据存储 public class MainActivity extends AppCompatActi ...

  7. 纯js生成QRCode

    纯js,不依赖jquery,非常好用,废话不多说,直接上代码! <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  8. Java的框架是什么意思

    框架就是一些类和接口的集合,通过这些类和接口协调来完成一系列的程序实现. JAVA框架可以分为三层:表示层,业务层和物理层.框架又叫做开发中的半成品,它不能提供整个WEB应用程序的所有东西,但是有了框 ...

  9. mybatis if标签比较字符串

    项目中需要在mybatis后台比较字符串 因为mybatis映射文件使用的是ognl表达式,所以不能使用 <if test="type == '0'"> 解决: < ...

  10. Qt Qwdget 汽车仪表知识点拆解3 进度条编写

    先贴上效果图,注意,没有写逻辑,都是乱动的 这篇我来说说左侧的这个进度条的实现原理,其实更简单,哈哈哈 有一个大的widget,根据素材,我放了10个label 剩下的就是写一个函数,根据数据的不同, ...