2021-5-15 vj补题
C - 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-trivial divisor 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 (1 ≤ q ≤ 1013). 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 6 is 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.
题意:给出一个数n,两个人轮流对其进行操作,把这个数换成他的非平凡因数(除了1和其本身的数)nn,如果那个人不能再对nn进行操作了,那他就赢了。在第一行中,打印获胜人的编号(1或2)。如果第一个玩家赢了,那么第二行应该包含另一个整数--他的第一个动作(如果第一个玩家连第一个动作都做不到,就打印0)。如果有多个解决方案,就打印其中任何一个。
题解:
当n为1或者质数时,找不到非平凡因数,所以第一个人一定赢;
当n为两个质数的乘积时,第二个人赢,因为第一个人要将该数换成它的非平凡数,而该数为质数,下一个人无法再进行操作。
其他情况时,第一个人只要把n换成是两个质数相乘而来的数就可以赢。
计算出n的所有质因数;
当n为8,那质因数为2,2,2;
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { ll n; cin>>n; if(n==1) { cout<<1<<"\n"<<0<<endl; } else{ ll q=n,ct=0; vector<ll>s; for(ll i=2;i*i<=n;i++)//找出所有质因数 { while(n%i==0) { s.push_back(i); n/=i; ++ct; } } if(n!=1&&n!=q)s.push_back(n),++ct;//此时的n为质数,所以要记录下来 if(ct>2)cout<<1<<endl,printf("%I64d\n",s[0]*s[1]); else if(ct==2)cout<<2<<endl; else cout<<1<<endl<<0<<endl; } }
D - Quantity of Strings
题意:给出字符串的长度n,可使用的字符种类m,求使得任意k个子字符串都是回文的方案有多少个;
题解:当k为1或者k>n时,种类有m^n个;
当k=n时,有m^((k+)/2)种;
当k为奇数时有m*m种;
偶数时有m种;
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll show(ll m,ll n) { ll ct=1; ll mod=1000000007; for(ll i=1;i<=n;i++) { ct*=m; ct%=mod; } return ct; } int main() { ll n,m,k; scanf("%lld%lld%lld",&n,&m,&k); if(k>n||k==1)printf("%lld\n",show(m,n)); else if(k==n)printf("%lld\n",show(m,(k+1)/2)); else if(k%2!=0)printf("%lld\n",m*m); else printf("%lld\n",m); }

浙公网安备 33010602011771号