zoukankan      html  css  js  c++  java
  • zoj 3529

    A Game Between Alice and Bob

    Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 524288/262144K (Java/Other)
    Total Submission(s) : 2   Accepted Submission(s) : 0
    Problem Description
    Alice and Bob play the following game. A series of numbers is written on the blackboard. Alice and Bob take turns choosing one of the numbers, and replace it with one of its positive factor but not itself. The one who makes the product of all numbers become 1 wins. You can assume Alice and Bob are intelligent enough and Alice take the first turn. The problem comes, who is the winner and which number is Alice's first choice if she wins?

     

    Input

    This problem contains multiple test cases. The first line of each case contains only one number N (1<= N <= 100000) representing there are N numbers on the blackboard. The second line contains N integer numbers specifying the N numbers written on the blackboard. All the numbers are positive and less than or equal to 5000000.

    Output

    Print exactly one line for each test case. The line begins with "Test #c: ", where c indicates the case number. Then print the name of the winner. If Alice wins, a number indicating her first choice is acquired, print its index after her name, separated by a space. If more than one number can be her first choice, make the index minimal.

    Sample Input

    4
    5 7 9 12
    4
    41503 15991 72 16057 
    

    Sample Output

    Test #1: Alice 1
    Test #2: Bob


    题目大意:给定n个数,每一步都可以将某个数替换为它的因子,但不能替换为本身,两个人轮流走,直到某个人走不了他就输了。问最后谁能赢,如果先手胜输出第一步。n<=10万,每个数<=5000000.

    解题思路:数论+Nim。初看起来好像无从下手,但是细想:本题要找它的因子替换他自己,那么可以从这里入手。而每个数都可以表示成x = p1^a1*p2^a2...pk^ak,pi为质数,这样每个数都由(a1+a2+..ak)个质数组成,然后就转换成若干堆质数,每次可以取走某堆的某些个质数,问最后谁取无可取。
          那不是传说中的裸Nim吗?把每堆的数量异或起来,结果为0为P态,先手负,结果非0,则先手胜,如果先手胜,必能与其中某个数异或后变成p态。若结果为ans,若每个数位a[i],则判断取走的那堆必须符合条件:temp = a[t] ^ ans,temp < a[t],这样的话a[i] ^ a[j] ^...a[t] = ans可表示成a[i] ^ a[j] ^...temp ^ ans = ans, 也就是a[i] ^ a[j] ^... ^ temp = 0。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    bool flag[5000005]={0};
    int cnt=0,prime[5000000];
    int sg[5000005];
    void Prime()
    {
    int i,j;
    for(i=2;i<=sqrt(1.0+5000000);i++)
    {
    if(flag[i])
    continue;
    prime[cnt++]=i;
    sg[i]=1;
    for(j=2;j*i<=sqrt(1.0+5000000);j++)
    flag[i*j]=true;
    }
    }
    int get_sg(int n)
    {
    if(sg[n]!=-1)
    return sg[n];
    int k=0,t=n,i;
    for(i=0;i<cnt&&prime[i]*prime[i]<=n;i++)
    if(n%prime[i]==0)
    {
    while(n%prime[i]==0)
    {
    k++;
    n/=prime[i];
    }
    }
    if(n>1)
    k++;
    return sg[t]=k;
    }
    int main()
    {
    memset(sg,-1,sizeof(sg));
    sg[1]=0;
    Prime();
    int n,cas=0,a[100000];
    while(scanf("%d",&n)!=EOF)
    {
    int ret=0;
    for(int i=0;i<n;i++)
    {
    scanf("%d",&a[i]);
    ret^=get_sg(a[i]);
    }
    printf("Test #%d: ",++cas);
    if(ret==0)
    puts("Bob");
    else
    {
    printf("Alice ");
    for(int i=0;i<n;i++)
    if(sg[a[i]]>(ret^sg[a[i]]))
    {
    printf("%d ",i+1);
    break;
    }
    }
    }
    return 0;
    }

  • 相关阅读:
    获取ip地址,
    手机div侧滑删除
    swiper左右选项卡滑动
    table-cell使用
    返回和刷新
    电脑浏览器计算高度和宽度
    css 空格
    时间js
    Nodejs仿Apache的部分功能
    Nodejs中的JavaScript
  • 原文地址:https://www.cnblogs.com/lxm940130740/p/3272386.html
Copyright © 2011-2022 走看看