題解:
這雖說不是一道難題,但是我也做了蠻久的。。。
思路:
- 輸入的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;
}