我解百度之星题目之" 剪刀石头布 "

/*
  Name:6.剪刀石头布
  Copyright:
  Author:
  Date: 28-05-06 08:51
  Description:
N个小孩正在和你玩一种剪刀石头布游戏(剪刀赢布,布赢石头,石头赢剪刀)。N个小孩中有一个是裁判,其余小孩分成三组(不排除某些组没有任何成员的可能性),但是你不知道谁是裁判,也不知道小孩们的分组情况。然后,小孩们开始玩剪刀石头布游戏,一共玩M次,每次任意选择两个小孩进行一轮,你会被告知结果,即两个小孩的胜负情况,然而你不会得知小孩具体出的是剪刀、石头还是布。已知各组的小孩分别只会出一种手势(因而同一组的两个小孩总会是和局),而裁判则每次都会随便选择出一种手势,因此没有人会知道裁判到底会出什么。请你在M次剪刀石头布游戏结束后,猜猜谁是裁判。如果你能猜出谁是裁判,请说明最早在第几次游戏结束后你就能够确定谁是裁判。

输入要求:
输入文件包含多组测试数据,每组测试数据第一行为两个整数N和M(1<=N<=500,0<M<=2000),分别为小孩的个数和剪刀石头布游戏进行的次数。接下来M行,每行两个整数且中间以一个符号隔开。两个整数分别为进行游戏的两个小孩各自的编号(为小于N的非负整数)。符号的可能值为“=”、“>”和“<”,分别表示和局、第一个小孩胜和第二个小孩胜三种情况。例:
3 3
0<1
1<2
2<0
3 5
0<1
0>1
1<2
1>2
0<2
4 4
0<1
0>1
2<3
2>3
1 0

 

输出要求:
1.每组测试数据输出一行,若能猜出谁是裁判,则输出裁判的编号,并输出在第几次游戏结束后就能够确定谁是裁判,小孩的编号和游戏次数以一个空格隔开;
2.如果无法确定谁是裁判,输出-2;如果发现剪刀石头布游戏的胜负情况不合理(即无论谁是裁判都会出现矛盾),则输出-1。例:
-2
1 4
-1
0 0

 

评分规则:
1.程序将运行在一台Linux机器上(内存使用不作严格限制),在每一测试用例上运行不能超过10秒,否则该用例不得分;
2.要求程序能按照输入样例的格式读取数据文件,按照输出样例的格式将运行结果输出到标准输出上。如果不能正确读入数据和输出数据,该题将不得分;
3.该题目共有5个测试用例,每个测试用例为一个输入文件。各测试用例占该题目分数的比例分别为5%、10%、15%、30%和40%;
4.该题目20分。
*/

/*
算法介绍:
1。如果只有1个人,参加比赛,那么他就是裁判,即输出:0 0 。
2。建立数组 players[MAX][MAX] 记录比赛结果(数组赋初值0),若选手a输给b,则players[a][b]=1,players[b][a]=3;若打平,则players[a][b]=players[b][a]=2;
注意:在记录成绩之前,先判断选手a,b 是否已经比赛过,如果已经比赛过,则判断先前的比赛结果是否与当前结果相同,若不相同,在数组judger[]中做标记(数组赋初值0),若judger[a]=0,使judger[a]=1,表示a有可能为裁判;若judger[a]=1,则使judger[a]=2,表示a肯定为裁判,因为他和两个人出现不同结果。
同理处理b。
3。遍历数组judger[],用temp1记录judger[i]=1出现的次数,用temp2记录judger[i]=2出现的次数,如果2个或以下的人可能为裁判,且没有人肯定为裁判,即if (temp1 <= 2 && temp2 == 0),则无法确定谁是裁判;
如果2个或以下的人可能为裁判,且有1人肯定为裁判,即if (temp1 <= 2 && temp2 == 1),则确定裁判i;
如果2个以上的人可能为裁判,即if (temp1 > 2),则胜负情况不合理。
*/

#include <iostream>
#include<fstream>
#include <time.h>

using namespace std;

const int MAX = 500;
void Readata(const char *filename);


int main()
{
 time_t startTime;
 time_t endTime;
 time(&startTime);

 Readata("in.txt");


 time(&endTime);
 cout << difftime(endTime, startTime) << endl;

 getchar();
 return 0;
}

void Readata(const char *filename)
{
      fstream in(filename);
      if (!in)
            return ;   //结束程序执行

      while (!in.eof())
      {
            int N, M;
            in >> N;
            in >> M;
           
            if (N == 1) //如果只有1个人,参加比赛,那么他就是裁判
                  cout << 0 << ' ' << 0 << endl;
                 
            int players[MAX][MAX] = {0};//记录比赛结果
            int *judger = new int[N];//记录是否可能为裁判,0表示不可能,1表示可能,2表示确定
            for (int i=0; i<N; i++)
                  judger[i] = 0;
                 
            int n = 0;//累计比赛场数
            int min = n;//存储能够确定谁是裁判的最少场数
            while (!in.eof() && n < M)//读入比赛结果信息
            {
                  char data[3]; //存储比赛选手编号和结果

                  in >> data[0];
                  in >> data[1];
                  in >> data[2];
                 // cout << data[0] << ' ' << data[1] << ' ' << data[2] << endl;
                  n++;
                  int flag = (data[1]=='<')? 1 :((data[1]=='=')? 2 : 3);//分别用1,2,3表示负,平,胜
                 
                  if (players[data[0]-'0'][data[2]-'0'] == 0)//若a,b未对局过,存储比赛结果
                  {
                        players[data[0]-'0'][data[2]-'0'] = flag;
                        players[data[2]-'0'][data[0]-'0'] = 4 - flag;
                  }
                  else if (players[data[0]-'0'][data[2]-'0'] != flag)//若a,b已对局过,且比赛结果不同
                  {
                        if (judger[data[0]-'0'] == 0) //a有可能为裁判
                              judger[data[0]-'0'] = 1;
                        else if (judger[data[0]-'0'] == 1)//a就是裁判
                        {
                              judger[data[0]-'0'] = 2;
                              min = n;
                        }
                       
                        if (judger[data[2]-'0'] == 0) //b有可能为裁判
                              judger[data[2]-'0'] = 1;
                        else if (judger[data[2]-'0'] == 1) //a就b是裁判
                        {
                              judger[data[2]-'0'] = 2;
                              min = n;
                        }
                  }
                 // cout << "players["<<data[0]-'0'<<"]["<<data[2]-'0'<<"]="<<players[data[0]-'0'][data[2]-'0']<<endl;
            }
            int temp1 = 0; //记录judger[i]=1出现的次数
            int temp2 = 0; //记录judger[i]=2出现的次数
            int answer;
            for (int i=0; i<N; i++)
            {
                  //cout << judger[i] << ' ';
                  if (judger[i] == 1)
                       temp1++;

                  if (judger[i] == 2)
                  {
                       temp2++;
                       answer = i;
                  }
            }
            cout << endl;
            if (temp1 <= 2 && temp2 == 0)
                  cout << -2 << endl;
            else  if (temp1 <= 2 && temp2 == 1)
                  cout << answer << ' ' << min << endl;
            else  if (temp1 > 2)
                  cout << -1 << endl;
                 
            delete []judger;
      }

    in.close(); //关闭文件
}

 

Posted on 2006-05-30 13:59 梦想飞扬 阅读(438) 评论(0)   编辑  收藏 引用

你可能感兴趣的:(我解百度之星题目之" 剪刀石头布 ")