题解:
这虽说不是一道难题,但是我也做了蛮久的。。。
思路:
- 输入的k,k对p和m,的目的就是为了求出n,然后得出n-1是多少。
- 已知了n-1(假设为n_1),开始对n_1分解质因数(比如9会分出两个3),记录下分解出的每个质因数的值及其出现的次数(用一个结构体来记录),然后对结构体排序(按照质因数的从大到小排序)。
- 然后输出结构体的信息:质因数的值(对应到素数系统的p),出现的次数(对应到素数系统的值数m)。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <deque>
#include <list>
#include <utility>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <iterator>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double E = exp(1.0);
const int MOD = 1e9+7;
const int MAX = 32+5;
int k;
int p[MAX];
int m[MAX];
int pow_int(int x,int y)
{
int res = 1;
for(int i = 1; i <= y; i++)
{
res *= x;
}
return res;
}
typedef struct PrimeDiv
{
int value;
int cnt;
}primeDiv;
// 分解质因数
vector <primeDiv> arr;// 保存了n-1的所有质因数
void get_div(int x)
{
for(int i = 2; i <= (int)sqrt(x); i++)
{
while(x % i == 0)
{
bool flag = false;
for(int j = 0; j < (int)arr.size(); j++)
{
if(arr[j].value == i)
{
arr[j].cnt++;
flag = true;
break;
}
}
if(!flag)
{
primeDiv t; t.value = i; t.cnt = 1;
arr.push_back(t);
}
x /= i;
}
}
if(x != 1)
{
primeDiv t; t.value = x; t.cnt = 1;
arr.push_back(t);
}
}
int cmp(primeDiv a,primeDiv b)
{
return a.value > b.value;
}
int main()
{
/*
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
*/
while(cin >> k)
{
arr.clear();
int n = 1;
for(int i = 0; i < k; i++)
{
cin >> p[i] >> m[i];
n *= pow_int(p[i],m[i]);
}
int n_1 = n - 1;
//cout << n_1 << endl;
get_div(n_1);
sort(arr.begin(),arr.end(),cmp);
for(int i = 0; i < (int)arr.size(); i++)
{
cout << arr[i].value << " " << arr[i].cnt << endl;
}
}
return 0;
}