A.小A能赢吗?
题目大意:小A小B从一堆石头里拿石头,每人每次拿1-3块石头,最后拿的人为赢家,小A先拿。两人都很聪明,给出石头总数,判断小A是否能赢,是输出Yes,否输出No
代码如下:
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int n, m;
cin >> n;
while ( n--){
cin >> m;
if ( m % 4 == 0)
cout << "No\n";
else
cout << "Yes\n";
}
return 0;
}
/**************************************************************
Problem: 10460
User: Danrt
Language: C++
Result: Accepted
Time:248 ms
Memory:1556 kb
****************************************************************/
此游戏属于组合游戏,可以用状态图来分析
1,2,3为必胜状态,4为必败状态,6,7,8可通过拿走1,2,3使后者处于必败状态,即6,7,8,为必胜状态
该游戏的结果只取决于始态,分析已知若n不是4的整数倍,则每次拿走n%4个石子,无论后者如何拿,始终会被前者置于n%4==0的状态。最终到达4状态即必败。
由此可知,n%4==0为必败状态,n%4 != 0 为必胜状态。
B.方阵
题目大意:小明参加了运动会方阵的训练,小明的位置在方阵的右后方,给出n*n矩阵的n,输出方阵对齐时小明能看到的人数
代码如下:
#include <cstdio>
#include <iostream>
using namespace std;
int eular(int n)
{
int ret=n, i;
for ( i = 2; i * i <= n;i++)
{
if ( n % i == 0)
{
ret = ret / i * ( i - 1);
while ( n % i == 0)
n /= i;
}
}
if ( n > 1)
ret = ret / n * ( n - 1);
return ret;
}
int main()
{
int n, s = 0, i, j, a[40010];
a[0] = 0;
a[1] = 0;
a[2] = 1;
for ( i = 3; i <= 40000; i++){
a[i] = a[i - 1] + eular( i);
}
while ( cin >> n){
if ( n == 1)
cout << 0 << endl;
else{
cout << a[n - 1] * 2 + 3<< endl;
}
}
return 0;
}
/**************************************************************
Problem: 10461
User: Danrt
Language: C++
Result: Accepted
Time:104 ms
Memory:1588 kb
****************************************************************/
将方阵按小明所在的对角线分开,利用欧拉函数易解。
其它的晚点再补吧,最近比较忙