八皇后问题 如何使用一句代码解决

qq_65364446 2024-11-20 15:35:40

八皇后问题 如何使用一句c++代码解决呢?

 

我看过类似的,别的语言写的一句搞定。但是,一句c++代码解决该问题的却没有哎,
有没有人知道?

...全文
390 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

Veni, vidi, vici~~~

#include <cstdio>
#include <algorithm>

// print pattern
void pp(int *p)
{
  for (int i = 0, j; i < 8; i++, puts(""))
    for (j = 0; j < 8; j++) printf("%c", p[i] == j ? 'Q' : '.');
  puts("");
}

// check pattern
#define cp(a, b) (1 << p[a]) & (1 << (p[b] + a - b)) || \
                 (1 << p[a]) & (1 << (p[b] - a + b))  

// solve EightQueens problem with one statement
int main()
{
  int p[] = {0, 1, 2, 3, 4, 5, 6, 7}, n = 0;

  while (std::next_permutation(p, p + 8))
    if (!(cp(0, 1) || cp(0, 2) || cp(0, 3) || cp(0, 4) || cp(0, 5) || 
          cp(0, 6) || cp(0, 7) || cp(1, 2) || cp(1, 3) || cp(1, 4) || 
          cp(1, 5) || cp(1, 6) || cp(1, 7) || cp(2, 3) || cp(2, 4) || 
          cp(2, 5) || cp(2, 6) || cp(2, 7) || cp(3, 4) || cp(3, 5) || 
          cp(3, 6) || cp(3, 7) || cp(4, 5) || cp(4, 6) || cp(4, 7) || 
          cp(5, 6) || cp(5, 7) || cp(6, 7))) n++, pp(p);

  printf("There are total %d patterns\n", n);

  return 0;
}
  • 打赏
  • 举报
回复

先在对角线上放上8个Q(这个排列当然是不符合要求的),然后检查其余8! - 1 = 40319种排列是否符合要求就可以了,因为每行只有一个Q,符合条件的必然是8行的某种排列。
你整个2^64次测试,不是超算就根本不可能有效时间之内算出来嘛~~~

qq_65364446 2024-11-22
  • 举报
回复
@日立奔腾浪潮微软松下联想 有这种一行的代码吗?你这样子的要求,一行好像写不出来哎
  • 举报
回复
@qq_65364446 不知道,有点困难,试一试
  • 举报
回复
@日立奔腾浪潮微软松下联想 一个语句是可以的,写成一行太长了
  • 打赏
  • 举报
回复

要求一行求出来,你写5行算什么事~

maguangzhi 2024-11-22
  • 打赏
  • 举报
回复

思路:a[8][8]数组,每个数组元素非0即1。8皇后要求每行只有一个元素为1(即全部行元素相加结果为1);若第1行异或第2行对应列元素,结果再异或第3行对应列元素,依次类推,如果最终异或结果的毎列全为1,即所有行的异或结果为0xFF,此时若任意45度或135度斜线上无皇后冲突,则为一个合法的8皇后布局。

方案:将a[8][8]数组用unsigned long long x即8*8=64位变量x存储,其中每个字节代表1行,不用相加即可简单判断每行只有一个元素为1(值为1,2,4,8,16,32,64,128中任意一个),这仅需一条语句即可;至于所有行对应列的异或运算也只需1条语句。任意45度或135度斜线不能有皇后冲突,可使用左移位或右移位实现。

编程:变量 x从0至2^64 -1=0xFFFFFFFFFFFFF循环一遍,即可求得所有可行解。若考虑8皇后问题的4个方向的对称性,则x从0至2^62 -1=0x3FFFFFFFFFFFFFFF循环一遍即可。如何取出8个字节其实很简单:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
for (unsigned long long x=0; x <= 0xFFFFFFFFFFFFFFFF; x++) {
unsigned char k, h, m, s, b[10], t[100], (&a)[8]=(unsigned char(&)[8])x; //a[k]代表8个字节
for (k=s=0; k < 8; s ^= a[k], k++){
if(!(a[k]==1||a[k]==2||a[k]==4||a[k]==8||a[k]==16||a[k]==32||a[k]==64||a[k]==128)) goto notq;
sprintf((char*)t + k * sizeof "1234567\n", "%8s\n", _itoa(a[k], (char*)b, 2));
}
for (k = 0; k < 7; k++)
for (h = k + 1; m = (h - k + 8) % 8, h < 8; h++)
if (a[k] == (a[h] << m) || a[k] == (a[h] >> m)) goto notq;
if (s == 0xFF) printf("%s\n\n", t); else notq:;
}
}
主函数内正好10行之内完成求解8皇后问题,简单验证x = 0x1040022004010880是一个解。当然,如果对求解过程进行一点优化,例如最后一个皇后位置直接确定(判定到a[7]即可,a[8]自动确定),代码就要变长但循环次数降为再除以8。更多有趣面试难点问题参见https://www.zhihu.com/question/825891126/answer/4843052142?utm_psn=1837747917399674880

  • 打赏
  • 举报
回复

只输出一种解可以:)

#include <stdio.h>
#include <string.h>

int main()
{
  char q[64];

  memset(q, '.', 64);
  for (int i = 0, x = 0x2be6388; i < 8; i++, x /= 10) q[i * 8 + x % 10] = 'Q';
  for (int i = 0; i < 8; i++) printf("%.8s\n", &q[i * 8]);

  return 0;
}

65,182

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧