2016郑州大学ACM/ICPC训练赛 Round5


A.小A能赢吗?

题目大意:小A小B从一堆石头里拿石头,每人每次拿1-3块石头,最后拿的人为赢家,小A先拿。两人都很聪明,给出石头总数,判断小A是否能赢,是输出Yes,否输出No

代码如下:

#include 
#include 
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 
#include 
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
****************************************************************/

将方阵按小明所在的对角线分开,利用欧拉函数易解。


其它的晚点再补吧,最近比较忙



你可能感兴趣的:(2016郑州大学ACM/ICPC训练赛 Round5)