2006 年百度之星程序设计大赛初赛题目 4
剪刀石头布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
输出样例
Can not determine
Player 1 can be determined to be the judge after 4 lines
Impossible
Player 0 can be determined to be the judge after 0 lines
说明:
共有 5 个测试数据集,每个测试数据集为一个输入文件,包含多组测试数据。每个测试数据集从易到难分别为 5 、 10 、 15 、 30 和 40 分,对每个测试数据集分别执行一次程序,每次必须在运行时限 3 秒内结束程序并输出正确的答案才能得分。
所有数据均从标准输入设备( stdin/cin )读入,并写出到标准输出设备 ( stdout/cout )中。
五个测试数据集中输入 N 分别不大于 20 、 50 、 100 、 200 和 500 ,各有 10 组测试数据。
example1:
/*剪刀石头布*/
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct numNod
{
int value;//小孩的编号
vector<int> win;//胜出的数字队列 暂定20个 以后编写动态增加数组后再修改
vector<int> lose;//输掉的数字队列 暂定20个 以后编写动态增加数组后再修改
numNod *next;
};//如果某个数字结构体的胜出队列中和失败队列中出现二次或者两次以上的同数字结果则说明这个数字是裁判
//另外值得注意的是只有裁判才会出现平局的情况
class Run
{
public:
Run();
int Compare( int num1, int num2, char sign );
private:
numNod *p;
int CheckUp();//检查函数,检查裁判是否已经得出
int numOfCheck;//猜拳进行的次数
numNod* SearchNum( int num );//查找p所指向队列是否有num这个数字结构,有的话返回指向num的地址,没有的话返回的地址是NULL
void ReworkList( numNod *p, char sign, int num2 );//第一种情况,给出指向数字结构体指针,输赢标志(1,2,3),比较对象(数字)
void ReworkList( int num1, char sign, int num2 ); //第二种情况,即结构体数字队列没有这个数字要重新生成
};
Run::Run()
{
this->p = NULL;
this->numOfCheck = 0;
}
numNod* Run::SearchNum( int num )
{
if( !this->p )
{
return NULL;
}
else
{
numNod *pTmp = this->p;
while( pTmp->value != num && pTmp->next )
pTmp = pTmp->next;
//至此查找完毕开始检测是否已经找到
if( pTmp->value == num )
{
return pTmp;
}
else
{
return NULL;
}
}
}
void Run::ReworkList( numNod *p, char sign, int num2 )
{
if( sign == '>' )
{
p->win.push_back( num2 );
}
else if ( sign == '<' )
{
p->lose.push_back( num2 );
}
else if( sign == '=' )//平局
{
p->win.push_back( num2 );
p->lose.push_back( num2 );
}
else//非法比较字符
{
cout << "Sign Error!" << endl;
return;
}
}
void Run::ReworkList( int num1, char sign, int num2 )
{
numNod *pTmp = this->p;
if( this->p == NULL )
{
this->p = new numNod;
this->p->next = NULL;
this->p->value = num1;
pTmp = this->p;
}
else
{
while( pTmp->next )
pTmp = pTmp->next;
pTmp->next = new numNod;
pTmp->next->value = num1;
pTmp->next->next = NULL;
pTmp = pTmp->next;
}
if( sign == '>' )
{
pTmp->win.push_back( num2 );
}
else if ( sign == '<' )
{
pTmp->lose.push_back( num2 );
}
else if( sign == '=' )//平局
{
pTmp->win.push_back( num2 );
pTmp->lose.push_back( num2 );
}
else//非法比较字符
{
cout << "Sign Error!" << endl;
return;
}
}
int Run::Compare( int num1, int num2, char sign )
{
numNod *pTmp;
int result(-1);
//检查队列有没有num1 和 num2 有点话处理 每有生成
pTmp = this->SearchNum( num1 );
if( pTmp )//如果已经有
{
this->ReworkList( pTmp, sign, num2 );
}
else
{
this->ReworkList( num1, sign, num2 );
}
//处理第二个数字
pTmp = this->SearchNum( num2 );
if( pTmp )//如果已经有
{
this->ReworkList( pTmp, sign, num1 );
}
else
{
this->ReworkList( num2, sign, num1 );
}
++ this->numOfCheck;
result = this->CheckUp();
if( result != -1 )
{
return result;
}
return -1;
}
int Run::CheckUp()//返回-1表示没有得出裁判,否则返回裁判的编号
{
numNod *pTmp = this->p;
int numOfSame = 0;//win lose列有相同有相同数字的次数
while( pTmp )
{
for( vector<int>::size_type i = 0; i < pTmp->win.size(); ++ i )
{
for( vector<int>::size_type j = 0; j < pTmp->lose.size(); ++ j )
{
if( pTmp->win == pTmp->lose )
++ numOfSame;
}
}
if( numOfSame > 1 )
{
return pTmp->value;//返回裁判数字编号
}
numOfSame = 0;
pTmp = pTmp->next;
}
return -1;
}
int main()
{
Run example1;
cout << "请输入选手人数 和 比赛次数" << endl;
int num1(0), num2(0);
cin >> num1 >> num2;
if( num1 == 1 && num2 == 0 )
{
cout << "Player 0 can be determined to be the judge after 0 lines" << endl;
return 0;
}
else if( num2 == 0 && num1 > 1 )
{
cout << "Can not determine " << endl;
return 0;
}
cout << "请输入" << num2 << "次的比赛结果,让程序来猜测裁判是谁,输入格式例如 1 < 0" << endl;
int num3(0), num4(0);
char sign;
//string string1;
int comparlines(0);
while( cin >> num3 >> sign >> num4 && comparlines < num2 )
{
//cout << "Debug:: string1:" << string1 << endl;
//num3 = string1;
//sign = string1;
//num4 = string1;
//cout << "Debug:: num3" << string1 << endl;
if( num3 < 0 || num3 > num1 || num4 < 0 || num4 > num1 )
{
cout << "存在选手编号非法输入,程序退出!" << endl;
return -1 ;
}
int rs = example1.Compare( num3, num4, sign );
if( rs != -1 )
{
cout << "Player" << rs << "can be determined to be the judge after " << comparlines << " lines" << endl;
return 0;
}
++ comparlines;
if( comparlines == num2 )
{
cout << " Can not determine " << endl;
return 0;
}
}
return 0;
}
、
来源:编程爱好者acm题库 Acm惹不起,呵呵 Acm惹不起,呵呵 eueis 发表于 2011-8-31 17:04 static/image/common/back.gif
一起交流!对这个话题感兴趣的朋友们
Acm 一般用C吧 {:3_41:}{:3_41:}
页:
[1]