【CodeForces - 151C】Win or Freeze (博弈,數學,唯一素數分解)
題幹:
You can't possibly imagine how cold our friends are this winter in Nvodsk! Two of them play the following game to warm up: initially a piece of paper has an integer q. During a move a player should write any integer number that is a non-trivialdivisor of the last written number. Then he should run this number of circles around the hotel. Let us remind you that a number's divisor is called non-trivial if it is different from one and from the divided number itself.
The first person who can't make a move wins as he continues to lie in his warm bed under three blankets while the other one keeps running. Determine which player wins considering that both players play optimally. If the first player wins, print any winning first move.
Input
The first line contains the only integer q
Please do not use the %lld specificator to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specificator.
Output
In the first line print the number of the winning player (1 or 2). If the first player wins then the second line should contain another integer — his first move (if the first player can't even make the first move, print 0). If there are multiple solutions, print any of them.
Examples
Input
6
Output
2
Input
30
Output
1 6
Input
1
Output
1 0
Note
Number 6 has only two non-trivial divisors: 2 and 3. It is impossible to make a move after the numbers 2 and 3 are written, so both of them are winning, thus, number 6is the losing number. A player can make a move and write number 6 after number 30; 6, as we know, is a losing number. Thus, this move will bring us the victory.
題目大意:
博弈問題,題目給了我們一個數,然後讓倆個人輪換操作:可以把這個數換成他的非平凡因數(但是不能是1和它本身),如果那個人不能操作了,那麼他就勝利。第一個人勝利,則輸出它的第一場操作。每個人都希望自己勝利,也就是不會失誤。
解題報告:
我們想要勝利,也就是想讓自己不能操作,也就是如果我製造出一個只有兩個質數的數,這樣對手只能取走其中一個,那麼我們走不動了,我們就贏了。所以我們面對一個數,我們的必敗態就是,它是由兩個素陣列成的。所以我們對n做唯一性分解這個題就做完了。再看一眼資料範圍,n可以等於1,所以加個特判。
AC程式碼:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
ll n;
ll biao[MAX];
int cnt;
bool is(ll x) {
for(ll i = 2; i*i<=x; i++) {
if(x%i==0) return 0;
}
return 1 ;
}
void fenjie(ll x) {
for(ll i = 2; i*i<=x; i++) {
if(x%i == 0 && is(i)) {
//biao[++cnt] = i;
while(x%i==0) biao[++cnt]=i,x/=i;
}
if(cnt>=2) break;
}
if(x>1) biao[++cnt]=x;
}
int main()
{
cin>>n;
if(n==1 || is(n)) {
puts("1");
puts("0");return 0 ;
}
fenjie(n);
if(cnt == 2 && biao[1]*biao[2] == n) {
puts("2");
}
else {
puts("1");
printf("%lld\n",biao[1]*biao[2]);
}
return 0 ;
}