博客
关于我
计算机猜数解答
阅读量:143 次
发布时间:2019-02-27

本文共 2613 字,大约阅读时间需要 8 分钟。

 

人和计算机做猜数游戏。人默想一个四位数,由计算机来猜。计算机将所猜的数显示到屏幕上,并问两个问题:一、有几个数字猜对了;二、猜对的数字中有几个位置也对了。人通过键盘来回答这两个问题。计算机一次又一次地猜,直到猜对为止。

为了简化输入输出,计算机每次输出一个四位数,然后人输入两个用空格分开的数,分别表示有几个数字猜对,有几个数字位置也对。右图是某次猜数过程:人默想的数是3422,奇数行是计算机猜的数,偶数行是人输入的信息。在这个例子中,计算机第五次猜中了数,在人输入4 4后程序结束退出。

请你写一个这样的猜数程序,看看你所想的数能在几次后被程序猜中。如果在猜数过程中,计算机发现人故意欺骗,输入了不正确的信息,那么程序将输出0然后直接退出。 

6897
0 0
5555
0 0
4444
1 1
4333
2 0
3422
4 4

 

#include <iostream>

#include <string>
#include <list>
#include <cmath>
#include <ctime>
#include <limits>
using namespace std;

list<string> numList;

void Initialize();

string RanddomNum();
int CountN(const string &guess, const string &str);
int CountP(const string &guess, const string &str);
string GetNextGuess();

int main()

{
 Initialize();   // 初始化
 string guess = "6789";//RanddomNum(); // 第1回合随机猜数
 int n, p;    // 分别表示有几个数字猜对,有几个数字位置也对
 while (1)
 {
  cout << guess << endl;
  cin >> n >> p;
  if (n == 4 && p == 4) // 猜中
   break;
  for (list<string>::iterator it = numList.begin();
   it != numList.end();)
  {
   if (CountN(guess, *it) != n) // 如果没有n个数字对
   {
    it = numList.erase(it);  // 不可能是被猜数,筛掉
    continue;
   }
   if (CountP(guess, *it) != p) // 如果没有p个数字位置对
   {
    it = numList.erase(it);  // 不可能是被猜数,筛掉
    continue;
   }
   ++it;
  }
  if (numList.empty()) // 没有候选数了,人欺骗计算机
  {
   cout << 0 << endl;
   break;
  }
  guess = GetNextGuess();
 }
 return 0;
}

void Initialize()

{
 char buf[5] = {0};
 for (int i = '1'; i <= '9'; i++)
  for (int j = '0'; j <= '9'; j++)
   for (int k = '0'; k <= '9'; k++)
    for (int l = '0'; l <= '9'; l++)
    {
     buf[0] = i;
     buf[1] = j;
     buf[2] = k;
     buf[3] = l;
     numList.push_back(buf);
    }
}

string RanddomNum()

{
 srand(time(NULL));
 int i = rand() % 9000 + 1000;
 char buf[5] = {0};
 sprintf(buf, "%d", i);
 return buf;
}

int CountN(const string &guess, const string &num)

{
 string s = num;  // 复制num,用于下面避免重复匹配的操作
 int count = 0;
 for (int i = 0; i < 4; i++) // 对guess中每一个数字
 {
  string::size_type pos = s.find(guess[i]);
  if (pos != string::npos)
  {
   count++;
   s[pos] = 'x';  // 为避免重复匹配,将它替换为字符’x’
  }
 }
 return count;
}

int CountP(const string &guess, const string &str)
{
 int count = 0;
 for (int i = 0; i < 4; i++)
  count += (guess[i] == str[i]);
 return count;
}

string GetNextGuess()

{
 int min = numeric_limits<int>::max();
 string guess;   // 猜这个数
 for (list<string>::iterator it = numList.begin();
  it != numList.end(); ++it)
 {
  int a[5][5] = {0};
  for (list<string>::iterator it2 = numList.begin();
   it2 != numList.end(); ++it2)
  {
   int x = CountN(*it, *it2);
   if (x == 0)
    a[0][0]++;    // 如果n=0,p一定=0
   else
    a[x][CountP(*it, *it2)]++;
  }
  int sum = 0;
  for (int i = 0; i < 5; i++)
   for (int j = 0; j <=i; j++) // 位置对的数字个数不会超过猜对的数字个数
    sum += a[i][j] * a[i][j];
  if (sum < min)
  {
   sum = min;
   guess = *it;
  }
 }
 return guess;
}

 

 

 

 

转载地址:http://xbgf.baihongyu.com/

你可能感兴趣的文章
mysql中having的用法
查看>>
MySQL中interactive_timeout和wait_timeout的区别
查看>>
mysql中int、bigint、smallint 和 tinyint的区别、char和varchar的区别详细介绍
查看>>
mysql中json_extract的使用方法
查看>>
mysql中json_extract的使用方法
查看>>
mysql中kill掉所有锁表的进程
查看>>
mysql中like % %模糊查询
查看>>
MySql中mvcc学习记录
查看>>
mysql中null和空字符串的区别与问题!
查看>>
MySQL中ON DUPLICATE KEY UPDATE的介绍与使用、批量更新、存在即更新不存在则插入
查看>>
MYSQL中TINYINT的取值范围
查看>>
MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
查看>>
Mysql中varchar类型数字排序不对踩坑记录
查看>>
MySQL中一条SQL语句到底是如何执行的呢?
查看>>
MySQL中你必须知道的10件事,1.5万字!
查看>>
MySQL中使用IN()查询到底走不走索引?
查看>>
Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
查看>>
MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
查看>>
mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
查看>>
mysql中出现Unit mysql.service could not be found 的解决方法
查看>>