中石油 6581 Fennec VS. Snuke

Fennec and Snuke are playing a board game.
On the board, there are N cells numbered 1 through N, and N−1 roads, each connecting two cells. Cell ai is adjacent to Cell bi through the i-th road. Every cell can be reached from every other cell by repeatedly traveling to an adjacent cell. In terms of graph theory, the graph formed by the cells and the roads is a tree.
Initially, Cell 1 is painted black, and Cell N is painted white. The other cells are not yet colored. Fennec (who goes first) and Snuke (who goes second) alternately paint an uncolored cell. More specifically, each player performs the following action in her/his turn:
Fennec: selects an uncolored cell that is adjacent to a black cell, and paints it black.
Snuke: selects an uncolored cell that is adjacent to a white cell, and paints it white.
A player loses when she/he cannot paint a cell. Determine the winner of the game when Fennec and Snuke play optimally.

Constraints
2≤N≤105
1≤ai,bi≤N
The given graph is a tree.

输入

Input is given from Standard Input in the following format:
N
a1 b1
:
aN−1 bN−1

输出

If Fennec wins, print Fennec; if Snuke wins, print Snuke.

翻译:

Fennec和Snuke正在玩棋盘游戏。
在电路板上,有N个电池编号为1到N,N-1个电路连接两个电池。Cell ai通过第i条道路与Cell bi相邻。通过重复前往相邻的小区,可以从每个其他小区到达每个小区。就图论而言,由细胞和道路形成的图是树。
最初,Cell 1涂成黑色,Cell N涂成白色。其他细胞尚未着色。Fennec(谁先走了)和Snuke(谁走了第二个)交替画了一个无色的细胞。更具体地说,每个玩家在她/她的回合中执行以下动作:
Fennec:选择与黑色单元格相邻的未着色单元格,并将其绘制为黑色。
Snuke:选择与白色单元相邻的无色单元,并将其涂成白色。
当一个玩家不能画一个小区时,玩家会输。当Fennec和Snuke最佳地发挥作用时,确定游戏的胜利者。
这个题很简单 ,但我做了好久,一开始时我开了两个队列,一边存F的,一边存S的,结果wa了,为什么呢,因为它扫的时候是从前往后扫,不能保证每一次都是最优的:下面是错误代码。

#include<stdio.h>
#include<queue>
#include<math.h>
#include<time.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(a) a&(-a)
#define PI acos(-1)
#define shortime(a)  std::ios::sync_with_stdio(a);
using  namespace std;
const LL mod=1e9+7;
//long long cmp(node a,node b){ if(a.x==b.x) return a.r>b.r;return a.x>b.x;}
//LL  quick(LL x,LL n){ LL ans=1,temp=x; while(n){if(n%2==1){ ans=(ans*temp)%mod;} n/=2;temp=temp*temp%mod;}return ans;}
int maxn (int a,int b,int c){return max(max(a,b),max(b,c));}
LL min(LL a,LL b) {return a<b?a:b;}
int gcd (int a,int b){return b==0?a:gcd(b,a%b);}
vector<int>a[100040];
queue<int>Q;
int main()
{
    int n,x,y;
    int vis[200005];
    mem(vis,0);
    scanf("%d",&n);
    for(int i=0;i<n-1;i++)
    {
        scanf("%d%d",&x,&y);
        a[x].push_back(y);
        a[y].push_back(x);
    }
    int num1=0,num2=0,flag=1;
    vis[1]=1,vis[n]=2;
    Q.push(1);
    Q.push(n);
    while(!Q.empty())
    {
        int temp;
        temp=Q.front();
        Q.pop();
        for(int i=0;i<a[temp].size();i++)
        {
            if(vis[a[temp][i]]==0)
            {
                Q.push(a[temp][i]);
                vis[a[temp][i]]=vis[temp];
                if(vis[temp]==1) num1++;
                else num2++;
            }
        }
    }
    if(num1>num2)
         printf("Fennec\n");
    else printf("Snuke\n");
    return 0;
}

看博客正解,非常简单,一个队列足以,直接用vis表示在哪个队中,太强了。。。。 

#include<stdio.h>
#include<queue>
#include<math.h>
#include<time.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(a) a&(-a)
#define PI acos(-1)
#define shortime(a)  std::ios::sync_with_stdio(a);
using  namespace std;
const LL mod=1e9+7;
//long long cmp(node a,node b){ if(a.x==b.x) return a.r>b.r;return a.x>b.x;}
//LL  quick(LL x,LL n){ LL ans=1,temp=x; while(n){if(n%2==1){ ans=(ans*temp)%mod;} n/=2;temp=temp*temp%mod;}return ans;}
int maxn (int a,int b,int c){return max(max(a,b),max(b,c));}
LL min(LL a,LL b) {return a<b?a:b;}
int gcd (int a,int b){return b==0?a:gcd(b,a%b);}
vector<int>a[200040];
queue<int>Q,P;
int main()
{
    int n,x,y;
    int vis[200005];
    mem(vis,0);
    scanf("%d",&n);
    for(int i=0;i<n-1;i++)
    {
        scanf("%d%d",&x,&y);
        a[x].push_back(y);
        a[y].push_back(x);
    }
    int num1=0,num2=0,flag=1;
    vis[1]=1,vis[n]=2;
    Q.push(1);
    P.push(n);
    while(1)
    {
        if(Q.empty()&&P.empty()) break;
        int temp;
        if(flag==1&&Q.empty()==0)
        {
            temp=Q.front();

            for(int i=0;i<a[temp].size();i++)
            {
                if(vis[a[temp][i]]==0)
                {
                    Q.push(a[temp][i]);
                    vis[a[temp][i]]=1;num1++;
                }
            }Q.pop();

        }
        else if(P.empty()==0){
            temp=P.front();

            for(int i=0;i<a[temp].size();i++)
            {
                if(vis[a[temp][i]]==0)
                {
                    P.push(a[temp][i]);
                    vis[a[temp][i]]=2; num2++;
                }
            }P.pop();

        }
        flag=-flag;
       // printf(".....%d\n",temp);
    }
    int sm=0,sn=0;
    /*for(i=0;i<n;i++)
    {
        if(vis[i]==1) sm++;
        else if(vis[i]==2) sn++;
    }
    if ()*/
    if(num1>num2)
         printf("Fennec\n");
    else printf("Snuke\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41485193/article/details/81348023