2014 Collage Tour - 2014 Topcoder Asia Competition B

Problem Statement

 You are given a long n. Return the largest divisor of n that is a perfect square. That is, the correct return value is x if and only if:
  1. x divides n
  2. There is an integer y such that x = y*y.
  3. x is the largest integer that satisfies conditions 1 and 2.

Definition

 
Class:SquareDivisor
Method:biggest
Parameters:long
Returns:long
Method signature:long biggest(long n)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):256

Constraints

-n will be between 1 and 10^18, inclusive.

Examples

0) 
 
12
Returns: 4
12 has six divisors: 1, 2, 3, 4, 6, and 12. Among them, only 1 and 4 are perfect squares. You should return the biggest one.
1) 
 
100
Returns: 100
2) 
 
2014
Returns: 1
3) 
 
999999875021574338
Returns: 499999937510787169
4) 
 
999999998000000002
Returns: 1

题意是给你一个64位整型n

让你找出满足条件n%x==0且x可以表示为一个整数的平方的最大x并输出

看到群里面有人说这个题是Miller Roban的模板题

但是好像也有比较巧妙的方法来做

在别人的代码里找到了一份答案,大概是看懂了

可以这样思考:

把n分解为i 和 n/i 

其中i的范围为[1, n^(1/3)],那么n/i的范围局势[n^(2/3), n]

我们采取这样的思路来做题:

首先判断n/i是否是一个平方数,如果是则判断当前的ans与n/i的大小,令ans取较大值

接着在判断(n/i)%i==0?

如果是,则说明n%(i*i) == 0

此时再判断ans 与 i*i的大小,令ans取较大值

依次遍历i即可保证遍历了n所有因子

代码如下:

#line 5 "SquareDivisor.cpp"
#include <map>
#include <set>
#include <cmath>
#include <string>
#include <cstring>
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXN 10010
#define LL long long
#define INF 0x7fffffff
using namespace std;

class SquareDivisor {
	public:
	long long biggest(long long n) {
        LL ret = 1;
        for(LL i=1; i*i*i<=n; ++i) {
            if(n % i == 0) {
                LL tmp = n/i;
                LL tg = sqrt(tmp*1.0)+0.5;
                if(tg*tg == tmp) {
                    if(tmp > ret)
                        ret = tmp;
                }
                if(tmp % i == 0) {
                    tg = i*i;
                    if(tg > ret)
                        ret = tg;
                }
            }
        }
        return ret;
    }
};

//this is for test
int main(void) {
    LL n;
	SquareDivisor test;
    while(cin >> n)
    	cout << test.biggest(n) << endl;
	return 0;
}
//test end


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值