一道算法的面试题

原贴出处:http://community.csdn.net/Expert/topic/5114/5114349.xml?temp=.2586939

据说做对第二题拿薪水1W不成问题 ,现在工资只有0.06w,做做看看

围棋考级的赛制是:
一共比赛5轮,和不同的对手比。
累计获胜2轮者通过,且不参加剩余的比赛。
连续4轮告负者不参加第5轮比赛。

在对手配对上,有个特别的规则:
就是每次都让胜率相同者配对比赛。
2个对手不能相遇2次或以上。

如:
第一轮,大家都是0胜0负
第二轮,就有1胜和1负2种胜率
第三轮,就有1胜1负和2负2种胜率
第四轮,就有1胜2负和3负2种胜率
第五轮,只有1胜3负1种胜率


第一题:请问这样的围棋考级的通过率是多少?

第二题:假设把所有选手根据原来的实力排个名次,假定名次高的必胜名次低的。
而比赛的配对是根据赛制再抽签,和原来的实力排名无关。
那么可能通不过的最高名次是第几名?
==============================================================================
分别用程序实现。
要求写出实现思路...
//

第一题简单,算算就出来了,答案是13/16

第二题的解题思想是尽量让实力相近的选手对战,这样才能尽量淘汰最高名次的

得到的答案是第8名

程序:

///

#include <iostream.h>

int opposer[20][4];//用于保存对手编号,为了2个对手不能相遇2次或以上


bool HaveMeet(int i,int j)
{
 for(int a=0;a<4;a++)
 {
  if(opposer[i][a]==j)
   return true;
 }
 return false;
}


void main()
{
 int wins[20];  //保存选手的胜率
 int matched[20];  //保存每轮是否已经参加比赛

 int i=0,j=0;
 for(;i<20;i++)
 {
  for(;j<4;j++)
  {opposer[i][j]=-1;}
 }

 for(i=0;i<20;i++)
 {wins[i]=0;matched[i]=0;}

 

 for(int k=0;k<4;k++)//4轮比赛
 {
  for(int m=0;m<20;m++)//每轮开始时将所有的选手设为未参加比赛
  {matched[m]=0;}

  for(i=0;i<20;i++)
  {
   if(wins[i]<2&&matched[i]==0)//如果这个选手需要参加且还没参加这轮比赛
   {
    for(j=i+1;j<20;j++)//循环查找它的对手
    {
     if((wins[i]==wins[j])&&(!HaveMeet(i,j))&&(matched[j]==0))//胜率相同且未对战过
     {
      //赢了
      wins[i]+=1;

      //保存对手状态
      opposer[i][k]=j;
      opposer[j][k]=i;

      //这2个选手已经比赛了
      matched[i]=1;
      matched[j]=1;
      break;
     }
    }
   }
  }
 }


//上4轮结束后只要找到第二个只赢了一场的棋手就是最大号淘汰选手
 i=0;
 while(wins[i]!=1)i++;
 i++;
 while(wins[i]!=1)i++;

 cout<<"可能通不过的最高名次是第"<<i+1<<"号"<<endl;

}
/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值