约数

试除法求约数

题目描述:

       给定 n 个正整数 ai,对于每个整数 ai,请你按照从小到大的顺序输出它的所有约数。

输入格式:

       第一行包含整数 n。

       接下来 n 行,每行包含一个整数 ai。

输出格式:

       输出共 n 行,其中第 i 行输出第 i 个整数 ai 的所有约数。

数据范围:

       1≤ n ≤100
       2≤ ai ≤2×10^9

输入样例:

2
6
8

输出样例:

1 2 3 6 
1 2 4 8 

解题代码: 

# include <iostream>
# include <vector>
# include <algorithm>
using namespace std;
vector <int> divisor(int x)
{
	vector <int>res;
	for (int i = 1;i<=x/i;i++)//将i<=sqrt(n)作为分界点,约数平均的分配在sqrt(n)两侧
	{
		if (x % i == 0)
		{
			res.push_back(i);//sqrt(n)左侧约数
			if (x / i != i)//当x/i=i时i*i=x为防止i约数重复加入,所以需要加判断条件
			{
				res.push_back(x / i);//sqrt(n)右侧约数
			}
		}
	}
	sort(res.begin(), res.end());
	return res;
}
int main()
{
	int n;
	cin >> n;
	while(n--)
	{
		int x;
		cin >> x;
		auto res=divisor(x);
		for (auto a : res)
		{
			cout << a << " ";
		}
		cout << endl;
	}
	return 0;
}

约数个数 

题目描述: 

        给定 n 个正整数 ai,请你输出这些数的乘积的约数个数,答案对 10^9+7 取模。

输入格式:

       第一行包含整数 n。

       接下来 n 行,每行包含一个整数 ai。

输出格式:

        输出一个整数,表示所给正整数的乘积的约数个数,答案需对 109+7 取模。

数据范围:

        1≤ n ≤100,
        1≤ ai ≤2×10^9

输入样例:

3
2
6
8

输出样例:

12

思路:

基于算术基本定理 

        N = (p1^x1)(p2^x2)(p3^x3)…(pk^xk)    其中p为质因子

       约数个数=(x1+1)(x2+1)(x3+1)…(xk+1)

例如:

        24=2 * 2 * 2 * 3=2^3 * 3

        用各个质因子的指数加一后再相乘即为此数的约数个数

        比如 (3+1)*(1+1)=4*2=8, 即表示24有8个约数。
        24的约数:1、2、3、4、6、8、12、24

1.先求出并存好各质因子的指数

for(int i=2;i<=a/i;i++)
		{
			while(a%i==0)
		{
			a /= i;
			primes[i]++;
		}
		}
		if(a!=1)
		{
			primes[a]++;
		}

2.然后将质因子指数加一相乘并膜上mod得到结果

long long int res = 1;
	for(auto p : primes) res = res * (p.second + 1) % mod;

解题代码:

# include <iostream>
# include <unordered_map>
using namespace std;
const int mod= 1e9 + 7;
int main()
{
	int n;
	cin >> n;
	unordered_map<int, int>primes;
	while(n--)
	{
		int a;
		cin >> a;
		for(int i=2;i<=a/i;i++)
		{
			while(a%i==0)
		{
			a /= i;
			primes[i]++;
		}
		}
		if(a!=1)
		{
			primes[a]++;
		}
	}
	long long int res = 1;
	for(auto p : primes) res = res * (p.second + 1) % mod;
	cout << res << endl;
	return 0;
}

约数之和 

题目描述: 

       给定 n个正整数 ai,请你输出这些数的乘积的约数之和,答案对 10^9+7 取模。

输入格式:

      第一行包含整数 n。

      接下来 n 行,每行包含一个整数 ai。

输出格式:

       输出一个整数,表示所给正整数的乘积的约数之和,答案需对 10^9+7 取模。

数据范围:

       1≤ n ≤100
       1≤ ai ≤2×10^9

输入样例:

3
2
6
8

输出样例:

252

思路: 

基于算术基本定理:

         N = (p1^x1)(p2^x2)(p3^x3)…(pk^xk)    其中p为质因子

        约数之和=(1+p1^1+p1^2……p1^x1)*……*(1+pk^1+pk^2……+pk^xk)

例如:

        24=2 * 2 * 2 * 3=2^3 * 3

        24的约数:1、2、3、4、6、8、12、24

        约数之和=(1+2^1+2^2+2^3)*(1+3^1)=60=1+2+3+4+6+8+12+24

1.先求出并存好各质因子的指数

for(int i=2;i<=a/i;i++)
		{
			while(a%i==0)
		{
			a /= i;
			primes[i]++;
		}
		}
		if(a!=1)
		{
			primes[a]++;
		}

2.用公式求得约数之和 

long long int res = 1;
	for(auto p : primes)
	{
		long long  a = p.first, b = p.second;
		long long  t = 1;
		while (b--) t = (t * a + 1) % mod;
		res = res * t % mod;
	}

 解题代码:

# include <iostream>
# include <unordered_map>
using namespace std;
const int mod= 1e9 + 7;
int main()
{
	int n;
	cin >> n;
	unordered_map<int, int>primes;
	while(n--)
	{
		int a;
		cin >> a;
		for(int i=2;i<=a/i;i++)
		{
			while(a%i==0)
		{
			a /= i;
			primes[i]++;
		}
		}
		if(a!=1)
		{
			primes[a]++;
		}
	}
	long long int res = 1;
	for(auto p : primes)
	{
		long long  a = p.first, b = p.second;
		long long  t = 1;
		while (b--) t = (t * a + 1) % mod;
		res = res * t % mod;
	}
	cout << res << endl;
	return 0;
}

 最大公约数

题目描述: 

        给定 n 对正整数 ai,bi 请你求出每对数的最大公约数。

输入格式:

       第一行包含整数 n。

       接下来 n 行,每行包含一个整数对 ai,bi。

输出格式:

       输出共 n 行,每行输出一个整数对的最大公约数。

数据范围:

        1≤n≤100000
        1≤ai,bi≤2×1000000000

输入样例:

2
3 6
4 6

输出样例:

3
2

解题代码:

辗转相除法:

# include <iostream>
using namespace std;
int gcd(int a,int b)
{
	return b ? gcd(b, a % b) : a;
}
int main()
{
	int n;
	cin >> n;
	while(n--)
	{
		int a, b;
		cin >> a >> b;
		int res=gcd(a, b);
		cout << res<<endl;
	}
	return 0;
}

 关于 a与b的公约数等于a与a%b的公约数的证明:

—设x是a与b的公约数,则x也是a-b的公约数;

—a%b=a-(a/b)*b,此处 a/b 为整除,令 a/b=c ,则 a%b=a-c*b,x是 a-c*b 的约数,即也是 a%b 的约数。

—设y是a%b的约数,则y也是a-c*b+c*b的约数,即y也是a的约数。

—综上所述, a与b的公约数等于a与a%b的公约数

图示: 

约数

上一篇:可迭代对象、迭代器、生成器


下一篇:2019第十届蓝桥杯C++B组Python解