牛客小白月赛11 J Rinne Loves Math
链接:https://ac.nowcoder.com/acm/contest/370/J
来源:牛客网
Rinne 刚刚学习了最简二次根式,于是她想用程序实现一个。
为了简化问题,在本题中,最简二次根式 a√bab 的定义为:
不存在b的一个因子k s.t. ∃x∈N∗,x2=k不存在b的一个因子k s.t. ∃x∈N∗,x2=k
即根号下的数字不含平方数因子。
举个最简二次根式的例子:√5,√200501175,20050117
举个不是最简的例子:√20,√44420,444
现在 Rinne 给了你形如 √nn 的式子中的 n,让你输出化简后的结果 a√bab 中的 a,b,如果这样的式子在实数范围内没有意义,输出 -1。
为了简化问题,在本题中,最简二次根式 a√bab 的定义为:
不存在b的一个因子k s.t. ∃x∈N∗,x2=k不存在b的一个因子k s.t. ∃x∈N∗,x2=k
即根号下的数字不含平方数因子。
举个最简二次根式的例子:√5,√200501175,20050117
举个不是最简的例子:√20,√44420,444
现在 Rinne 给了你形如 √nn 的式子中的 n,让你输出化简后的结果 a√bab 中的 a,b,如果这样的式子在实数范围内没有意义,输出 -1。
输入描述:
第一行一个整数 T,表示数据组数。
接下来 T 行,每行一个整数 x 表示根号下的数。
输出描述:
输出一共 T 行,每行两个数表示 √xx 化简后的答案 a,b
示例1
备注:
T≤100,0<|x|≤107
这个题我们会长大人是用唯一分解和快速幂做的
这里贴上他的代码(先膜拜巨神一波):
#include <set> #include <map> #include <deque> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <bitset> #include <cstdio> #include <string> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; typedef pair<LL, LL> pLL; typedef pair<LL, int> pLi; typedef pair<int, LL> pil;; typedef pair<int, int> pii; typedef unsigned long long uLL; #define lson rt<<1 #define rson rt<<1|1 #define lowbit(x) x&(-x) #define name2str(name) (#name) #define bug printf("*********\n") #define debug(x) cout<<#x"=["<<x<<"]" <<endl #define FIN freopen("D://code//in.txt","r",stdin) #define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8; const int mod = 1000000007; const int maxn = 4e3 + 7; const double pi = acos(-1); const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3fLL; int t, x, m; int p[maxn], isp[maxn]; void init() { for(int i = 2; i < maxn; i++) p[i] = 1; for(int i = 2; i * i < maxn; i++) { if(p[i]) { for(int j = i * i; j < maxn; j += i) { p[j] = 0; } } } for(int i = 2; i < maxn; i++) { if(p[i]) isp[m++] = i; } } int qpow(int x, int n) { int res = 1; while(n) { if(n & 1) res = res * x; x = x * x; n >>= 1; } return res; } int main(){ init(); scanf("%d", &t); while(t--) { int num1 = 1, num2 = 1; scanf("%d", &x); if(x < 0) { printf("-1\n"); continue; } for(int j = 0; j < m; j++) { if(x % isp[j] == 0) { int cnt = 0; while(x % isp[j] == 0) { cnt++; x /= isp[j]; } num1 *= qpow(isp[j], cnt / 2); if(cnt & 1) num2 *= isp[j]; } } if(x > 1) num2 *= x; printf("%d %d\n", num1, num2); } return 0; }
而菜鸡我是先预处理一波找出所有的平方的(当然你甚至可以打表才3126个数而已)
注意这里要从大往小判断
因为36是4*9得来的本身就是一个平方数,所有从大往小会好很多
#include<bits/stdc++.h> typedef long long ll; using namespace std; const int N=10000005 ; ll a[10000005]; int main() { int m,T; ll n; scanf("%d",&T); for(int i=1;i<=N;i++) { a[i]=i*i; } while(T--) { scanf("%lld",&n); if(n<0) { printf("-1\n"); continue; } int l=1,r=sqrt(n); for(int i=r+1;i>=1;i--) { if(n%a[i]==0) { ll t=sqrt(a[i]); printf("%lld %lld\n",t,n/a[i]); break; } } } return 0; }