花褪残红青杏小。燕子飞时,绿水人家绕。

C++之电脑猜数

菜鸟编程 十五楼的鸟儿 27833浏览 0评论

题目要求:
人和计算机做猜数游戏。人默想一个四位数,由计算机来猜。计算机将所猜的数显示到屏幕上,并问两个问题:一、有几个数字猜对了;二、猜对的数字中有几个位置也对了。人通过键盘来回答这两个问题。计算机一次又一次地猜,直到猜对为止。
为了简化输入输出,计算机每次输出一个四位数,然后人输入两个用空格分开的数,分别表示有几个数字猜对,有几个数字位置也对。右图是某次猜数过程:人默想的数是3422,奇数行是计算机猜的数,偶数行是人输入的信息。在这个例子中,计算机第五次猜中了数,在人输入4 4后程序结束退出。

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

#include

#include
#include#include
#include
#includeusing namespace std;

listnumList;

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::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::max();
string guess;   // 猜这个数
for (list::iterator it = numList.begin();
 it != numList.end(); ++it)
{
 int a[5][5] = {0};
 for (list::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;
}
C++之电脑猜数 C/CPP 菜鸟编程  第1张

转载请注明:鸟儿博客 » C++之电脑猜数

游客
发表我的评论 换个身份
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址