2021年7月26日 构造、博弈论训练题题解
【新人,拿这篇博客练练手,大佬们轻喷QAQ】
训练题都来源于cf hdu等各大OJ,这里就不标记出处了。(其实就是我懒)
- A - Matches Game
Here is a simple game. In this game, there are several piles of matches and two players. The two player play in turn. In each turn, one can choose a pile and take away arbitrary number of matches from the pile (Of course the number of matches, which is taken away, cannot be zero and cannot be larger than the number of matches in the chosen pile). If after a player’s turn, there is no match left, the player is the winner. Suppose that the two players are all very clear. Your job is to tell whether the player who plays first can win the game or not.
Input
The input consists of several lines, and in each line there is a test case. At the beginning of a line, there is an integer M (1 <= M <=20), which is the number of piles. Then comes M positive integers, which are not larger than 10000000. These M integers represent the number of matches in each pile.Output
For each test case, output "Yes" in a single line, if the player who play first will win, otherwise output "No".
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
while(cin>>n){
int a;
int ans=0;
for(int i=0;i<n;++i){
cin>>a;
ans^=a;
}
if(ans==0) cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
return 0;
}
- B - Georgia and Bob
Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, number the grids from left to right by 1, 2, 3, ..., and place N chessmen on different grids, as shown in the following figure for example:
Georgia and Bob move the chessmen in turn. Every time a player will choose a chessman, and move it to the left without going over any other chessmen or across the left edge. The player can freely choose number of steps the chessman moves, with the constraint that the chessman must be moved at least ONE step and one grid can at most contains ONE single chessman. The player who cannot make a move loses the game.
Georgia always plays first since "Lady first". Suppose that Georgia and Bob both do their best in the game, i.e., if one of them knows a way to win the game, he or she will be able to carry it out.
Given the initial positions of the n chessmen, can you predict who will finally win the game?Input
The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. Each test case contains two lines. The first line consists of one integer N (1 <= N <= 1000), indicating the number of chessmen. The second line contains N different integers P1, P2 ... Pn (1 <= Pi <= 10000), which are the initial positions of the n chessmen.Output
For each test case, prints a single line, "Georgia will win", if Georgia will win the game; "Bob will win", if Bob will win the game; otherwise 'Not sure'.
点击查看代码
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int t;cin >> t;
while(t--){
int n;
cin >> n;
int a[1010];
for(int i=1;i<=n;++i){
cin >> a[i];
}
if(n%2==1){
a[++n]=0;
}
sort(a+1,a+n+1);
int sum=0;
for(int i=1;i<=n;i+=2){
sum^=(a[i+1]-a[i]-1);
}
if(sum==0){
cout << "Bob will win" << endl;
}else{
cout << "Georgia will win" << endl;
}
}
return 0;
}
- C - Deleting Divisors
Alice and Bob are playing a game.
They start with a positive integer nn and take alternating turns doing operations on it. Each turn a player can subtract from nn one of its divisors that isn't 11 or nn. The player who cannot make a move on his/her turn loses. Alice always moves first.
Note that they subtract a divisor of the current number in each turn.
You are asked to find out who will win the game if both players play optimally.
InputThe first line contains a single integer t (1≤t≤104) — the number of test cases. Then t test cases follow.
Each test case contains a single integer n (1≤n≤109) — the initial number.
OutputFor each test case output "Alice" if Alice will win the game or "Bob" if Bob will win, if both players play optimally.
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
long long n;
cin >> n;
if (n % 2 == 1) {
cout << "Bob" << endl;
} else {
long long p = 0;
while (n % 2 == 0) {
n /= 2;
++p;
}
if (n != 1) {
cout << "Alice" << endl;
} else {
if (p % 2 == 1) {
cout << "Bob" << endl;
} else {
cout << "Alice" << endl;
}
}
}
}
return 0;
}
- D - 取石子游戏
1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜.先取者负输出"Second win".先取者胜输出"First win".Input
输入有多组.每组第1行是2<=n<2^31. n=0退出.
Output先取者负输出"Second win". 先取者胜输出"First win".
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
long long t[10010];
t[0]=1;t[1]=1;
int i;
for(i=2;;++i){
if(t[i-1]+t[i-2]>2147483647){
break;
}
else{
t[i]=t[i-1]+t[i-2];
}
}
--i;
int a;
cin>>a;
while(a){
bool flag=true;
for(int z=1;z<=i;++z){
if(a==t[z]){
flag=false;
break;
}
if(a>t[z]&&a<t[z+1]){
break;
}
}
if(flag){
cout<<"First win"<<endl;
}else{
cout<<"Second win"<<endl;
}
cin>>a;
}
return 0;
}
- E - A Multiplication Game
Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 to 9. Stan always starts with p = 1, does his multiplication, then Ollie multiplies the number, then Stan and so on. Before a game starts, they draw an integer 1 < n < 4294967295 and the winner is who first reaches p >= n.Input
Each line of input contains one integer number n.
Output
For each line of input output one line either
Stan wins.
or
Ollie wins.
assuming that both of them play perfectly.
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
double n;
while(cin>>n){
while(n>18){
n/=18;
}
if(n>9){
cout<<"Ollie wins."<<endl;
}
else{
cout<<"Stan wins."<<endl;
}
}
return 0;
}
- F - Hack it!
Little X has met the following problem recently.
Let's define f(x) as the sum of digits in decimal representation of number x (for example, f(1234) = 1 + 2 + 3 + 4). You are to calculate
Of course Little X has solved this problem quickly, has locked it, and then has tried to hack others. He has seen the following C++ code:
ans = solve(l, r) % a; if (ans <= 0) ans += a;
This code will fail only on the test with . You are given number a, help Little X to find a proper test for hack.
Input
The first line contains a single integer a (1 ≤ a ≤ 1018).
Output
Print two integers: l, r (1 ≤ l ≤ r < 10200) — the required test data. Leading zeros aren't allowed. It's guaranteed that the solution exists.
点击查看代码
import java.math.*;
import java.util.*;
public class Hack_it {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
String s=in.nextLine();
BigInteger a=new BigInteger(s);
BigInteger m=new BigInteger("81000000000000000000");
BigInteger t=m.mod(a);
BigInteger l=a.subtract(t);
BigInteger r=l.subtract(new BigInteger("1")).add(new BigInteger("1000000000000000000"));
System.out.println(l+" "+r);
in.close();
}
}