京东2016实习生在线编程题

选举游戏


解题思路
不断寻找数组中的最大值,若最大值不是小东,则争取当前投票数最大的候选人1票,直到最大值为小东。这种方法耗时会比较久,但是对于n不是特别大的情况还是可以接受的。
以下代码是100%通过。

#include<iostream>
using namespace std;
int main(){
    int n;
    int a[105];
    while(cin>>n){
          int max=0;
          int maxi=0;
        for(int i=0;i<n;i++){
              cin>>a[i];
              if(max<=a[i]){
                    max=a[i];
                    maxi=i;
              }
        }
          int ans=0;
          while(maxi!=0){
            a[0]++;
            a[maxi]--;
            ans++;
            max=0;
            maxi=0;
            for(int i=0;i<n;i++)
                      if(max<=a[i]){
                        max=a[i];
                        maxi=i;
                      }
          }
          cout<<ans<<endl;
    }
      return 0;
}

三子棋


这个题目只过了60%,实在不知道没有考虑到哪里。
计算画叉的人的下棋数目x,画圈的人下棋数目o,空白的数目为d。

  1. 首先判断棋局是否不合法
    给定棋局不合法的情况包括:
    • o+d+x!=9
    • x>o
    • x-o>1
    • 画叉赢,并且画圈也赢
  2. 然后判断是否有画叉或画圈的获胜
  3. 如果d=0,则为平局
  4. 最后判断下一轮先下棋的人
#include<iostream>
#include<stdio.h>
using namespace std;
char a[3][3];
bool valid(char c){
    //cout<<1<<endl;
    // 水平
    for(int i=0;i<3;i++){
        int j=0;
        for(;j<3;j++)
            if(a[i][j]!=c)break;
        if(j==3)return true;
    }
    //cout<<2<<endl;
    // 垂直
    for(int i=0;i<3;i++){
        int j=0;
        for(;j<3;j++)
            if(a[j][i]!=c)break;
        if(j==3)return true;
    }
    //cout<<3<<endl;
    // 对角
    int i=0;
    for(;i<3;i++)
        if(a[i][i]!=c)break;
    if(i==3)return true;
    for(i=0;i<3;i++)
        if(a[i][2-i]!=c)break;
    if(i==3)return true;
    return false;
}
int main(){

    while(scanf("%s",a[0])!=EOF){
        //getchar();
        for(int i=1;i<=2;i++){
            scanf("%*c%s",a[i]);
            //getchar();
        }
        //for(int i=0;i<3;i++){
        //  for(int j=0;j<3;j++)
        //      cout<<a[i][j];
        //  cout<<endl;
        //}
        int x=0;
        int o=0;
        int d=0;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++)
                if(a[i][j]=='X')x++;
                else
                    if(a[i][j]=='0')o++;
                    else
                        if(a[i][j]=='.')d++;
        }
        if((x+o+d)!=9||abs(x-o)>1||o>x){
            cout<<"x"<<endl;
            continue;
        }
        bool vx=valid('X');
        bool vo=valid('0');
        if(vx&&vo){
            cout<<"x"<<endl;
            continue;
        }
        if(vx){
            cout<<"1 won"<<endl;
            continue;
        }
        if(vo){
            cout<<"2 won"<<endl;
            continue;
        }
        if(d==0){
            cout<<"draw"<<endl;
            continue;
        }
        if(x==o){
            cout<<"1"<<endl;
        }else{
            cout<<"2"<<endl;
        }
    }
}

在别人的题解里看到,棋局不合法还有一种情况:叉或圈存在多个赢的情况,以叉为例,存在直线两条以上或者存在一条水平一条垂直等情况。对以上代码的valid函数进行修改,使用一个变量flag记录赢的次数(让其获胜的情况,即记录几条水平、几条垂直、几条对角),对特殊棋局判断是否合法。valid返回为0,没有获胜;返回为1,对应的选手获胜;返回为-1,说明棋局不合法。

#include<iostream>
#include<stdio.h>
using namespace std;
char a[3][3];
int valid(char c){
    // 水平
    int flag=0;
    for(int i=0;i<3;i++){
        int j=0;
        for(;j<3;j++)
            if(a[i][j]!=c)break;
        if(j==3)flag++;
    }
    // 垂直
    for(int i=0;i<3;i++){
        int j=0;
        for(;j<3;j++)
            if(a[j][i]!=c)break;
        if(j==3)flag++;
    }
    // 对角
    int i=0;
    for(;i<3;i++)
        if(a[i][i]!=c)break;
    if(i==3)flag++;
    for(i=0;i<3;i++)
        if(a[i][2-i]!=c)break;
    if(i==3)flag++;
    if(flag==0||flag==1)return flag;
    return -1;
}
int main(){

    while(scanf("%s",a[0])!=EOF){
        //getchar();
        for(int i=1;i<=2;i++){
            scanf("%*c%s",a[i]);
            //getchar();
        }
        //for(int i=0;i<3;i++){
        //  for(int j=0;j<3;j++)
        //      cout<<a[i][j];
        //  cout<<endl;
        //}
        int x=0;
        int o=0;
        int d=0;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++)
                if(a[i][j]=='X')x++;
                else
                    if(a[i][j]=='0')o++;
                    else
                        if(a[i][j]=='.')d++;
        }
        if((x+o+d)!=9||abs(x-o)>1||o>x){
            cout<<"x"<<endl;
            continue;
        }
        int vx=valid('X');
        int vo=valid('0');
        if(vx==-1||vo==-1||vx&&vo){
            cout<<"x"<<endl;
            continue;
        }
        if(vx){
            cout<<"1 won"<<endl;
            continue;
        }
        if(vo){
            cout<<"2 won"<<endl;
            continue;
        }
        if(d==0){
            cout<<"draw"<<endl;
            continue;
        }
        if(x==o){
            cout<<"1"<<endl;
        }else{
            cout<<"2"<<endl;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值