根式化简的多种奇妙解法

 弱者的第一篇博客

题目描述:

 

解法 1:

(弱者初学c时想到的代码,时间复杂度较高)

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
#include<string.h>
#include<cmath>
#include <algorithm>
#include<math.h>


using namespace std;
int main()
{
	long long a, c = 0, b;
	long long t = 1, h = 1;
	while (scanf("%lld", &a) != EOF)

	{
		for (b = 1; b * b <= a; b++)
		{
			long long q = b * b;//逐一枚举每个小于sqrt(a)的数,去寻找符合的值;
			if (a % q == 0)
			{
				t = b;
				h = a / q;//因数是对衬的因此可以通过小的数去找大的因数,减少时间复杂度;
			}
		}
		c++;
		if (h == 1)
		{
			printf("Case #%d: %d\n", c, t);
		}
		else if (t == 1)
		{
			printf("Case #%d: sqrt(%d)\n", c, a);
		}
		else
			printf("Case #%d: %d*sqrt(%d)\n", c, t, h);
	}
	return 0;
}

                                                                   解法2:

                               (弱者借来的代码,读书人的事不能叫偷(手动狗头))

解法1和解法2思想上大致相同;

#include<bits/stdc++.h>

using namespace std;

int main()
{
	int cnt = 1, x;
	while (cin >> x)
	{
		int a = sqrt(x);
		if (a * a == x)printf("Case #%d: %d\n", cnt++, a);
		else
		{
			while (x % (a * a) != 0)a--;//大体上解法1和解法2思想一致;
			if (a == 1)
			{
				printf("Case #%d: sqrt(%d)\n", cnt++, x);
			}
			else
			{
				printf("Case #%d: %d*sqrt(%d)\n", cnt++, a, x / (a * a));
			}
		}
	}

	return 0;
}

                                                                  解法3

   

(解法三是弱者初学c++,70天想到的奇妙解法,时间复杂度相对较低,但代码长度就另说)

可以想像成树:

 我们所需要的是树的最底端各个数的值和数出现的次数

#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include<iostream>
typedef long long ll;
using namespace std;
const int N = 32000;
ll x;
ll find(int x)//查找除1外的最小因数(作用:用于对映最大因数)
{
	ll ans=0;
	for (int i = 2; i * i <= x; i++)
	{
		if (x % i == 0)
		{
			ans = x / i;
		}
		if (ans != 0)return ans;
	}

	}
bool isprime(int n) {//素数判断
	if (n <= 1) return false;
	if (n == 2 || n == 3) return true;
	if (n % 6 != 1 && n % 6 != 5) return false;
	for (int i = 5; i * i <= n; i += 6) if (n % i == 0 || n % (i + 2) == 0) return false;
	return true;
}
struct cnm {
	ll ci;//储存小于sqrt(x)素数的个数
	ll su;//大于x的素数个数
};
void dg(ll a,cnm num[]) {
	ll b;
	int c;
	if (isprime(a) ) {
		if (a < sqrt(x))//使用sqrt(x)来降低时间复杂度,以及减少空间的使用,不然结构体数组炸了;
		{
			num[a].ci++;
		}
		else {
			num[x / a].su ++;
		}
	}
	else {
		c = find(a);
		b = a / c;
		dg(b,num);//递归去寻找
		dg(c, num);
	}

}

int main()
{
	
	
	ll i = 0;
		while(cin >> x)
		{
			i++;
			cnm num[N] = { 0 };
		ll a=1, b=1;
		if (isprime(x))printf("Case #%d: sqrt(%lld)\n", i, x);
		else {
			if ((ll)sqrt(x) * (ll)sqrt(x) == x)printf("Case #%d: %lld\n", i,(ll)sqrt(x));
			else {
				dg(x,num);
				for (int j = 1; j <=sqrt(x); j++)
				{
					if (num[j].ci >= 2||num[j].su>=2) {
						if (num[j]. ci >= 2)
						{
							for (int k = 1; k <= num[j].ci / 2; k++)//大于2个就可以去该素数的值
							{
								a = a * j;
							}
							num[j].ci = num[j].ci % 2;
						}
						if (num[j].su >= 2)
						{
							for (int k = 1; k <= num[j].su / 2; k++)
							{
								a = a * (x/j);
							}
							num[j].su = num[j].su % 2;
						}
					}
					if (num[j].ci >= 1||num[j].su>=1) {//只剩下一个的素数只能放在根号里面;
						if(num[j].ci>=1)
						  b = b * j;
						if (num[j].su >= 1)
							b = b * (x / j);
					}
				}
					if(a==1)
					printf("Case #%d: sqrt(%lld)\n", i, b);
					else 
				printf("Case #%d: %lld*sqrt(%lld)\n", i, a,b);
			}
		}

	}
}

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值