能在0.02秒内找到最优解的华容道程序

news/2025/10/27 8:23:18/文章来源:https://www.cnblogs.com/funwithwords/p/19167771

https://www.cnblogs.com/funwithwords/p/19158097

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <immintrin.h>
#include <xmmintrin.h>
#include <set>
#include "cwisstable.h"const char* NM[][4] = { {"","","",""}, {"西",""}, {"",""}, {"",""}, {"",""}, {"",""}, {""}, {""}, {""}, {""} };
int W[] = { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1 }; // 默认5个水平条,随后修改
int H[] = { 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int T[10]; // Type
const int D[][2] = { {0, 1}, {0, -1}, {-1, 0}, {1, 0} }; // 后面有两处用下标判断移动方向enum { MAX = 3600 * 10000 };
struct State {uint8_t aa[10][2];
#define CCY aa[0][0] // 曹操的yint p; // 局面路径的previous
#define cpy20(dst, src) _mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((__m128i*)src)); *(int*)((uint8_t*)dst+16) = *(int*)((const uint8_t*)src+16)void operator= (const State& s) { cpy20(aa, s.aa); p = s.p; }void operator=(const char* s);void print(const char* s = "");
} q[MAX + 10 * 4]; // 最多40个move. MAX很大; 没判断qt < MAX
int qh, qt = 1; // queue head, tailvoid State::operator= (const char* s) {int p = 6;for (int x = 3; x >= 0; x--)for (int y = 4; y >= 0; y--) {#define CASE(c, i) case c: aa[i][1] = x; aa[i][0] = y; break;switch (s[x * 5 + y]) {// 曹关张黄子龙(l)马CASE('c', 0) CASE('g', 1) CASE('z', 2) CASE('h', 3) CASE('l', 4) CASE('m', 5)case 'p':aa[p][1] = x; aa[p++][0] = y; break; // pawn
    }}static const char*  S[] = { "gg", "zz", "hh", "ll", "mm" };for (int i = 0; i < 5; i++) if (strstr(s, S[i])) W[i+1] = 1, H[i+1] = 2;for (int i = 0; i < 10; i++) T[i] = W[i] * 2 + H[i] - 2;
}#define set2DArrayByCoordInA(a, b, what) for (int i = 0; i < 10; i++) { \const int x = a[i][1], y = a[i][0]; \for (int yy = y; yy < y + H[i]; yy++) \for (int xx = x; xx < x + W[i]; xx++) b[yy][xx] = what; \
}void State::print (const char* s) {int idx[10] = {};const char* b[5][4] = {};set2DArrayByCoordInA(aa, b, NM[i][idx[i]++])for (int y = 0; y < 5; y++) {for (int x = 0; x < 4; x++) printf("%s", b[y][x] ? : " ");puts("");}printf("%s\n", s);
}void print_path () { // 数组存的单链表就地翻转int prev = -1, next = -1, n = 0;for (int cur = qh; cur != -1; ++n) {next = q[cur].p; q[cur].p = prev;prev = cur; cur = next;}for (int p = 0; p != -1; p = q[p].p) q[p].print();printf("%d\n", n);
}#pragma pack(1)
struct {uint8_t b[5][4];uint64_t n; // unique numberuint8_t _[4];
} u __attribute__((aligned(32)));
#pragma pack()#define Ah { \_mm256_store_si256((__m256i*)&u, _mm256_setzero_si256()); \set2DArrayByCoordInA(a, u.b, T[i]) \for (int y = 0; y < 5; y++) \for (int x = 0; x < 4; x++) u.n = u.n * 5 + u.b[y][x]; \
}#ifdef st
CWISS_DECLARE_FLAT_HASHSET(Set, uint64_t); Set set = Set_new(MAX);
#define if_ok_add_state if (ok) { cpy20(q[qt].aa, a); \Ah if (!Set_contains(&set, &u.n)) { Set_insert(&set, &u.n); q[qt++].p = qh; } \
}
#else
std::set<uint64_t> set;
#define if_ok_add_state if (ok) { cpy20(q[qt].aa, a); \Ah if (set.find(u.n) == set.end()) { set.insert(u.n); q[qt++].p = qh; } \
}
#endifint main (int argc, char* argv[]) {//q[0] = "pp zz""ccghh""ccgll""pp mm";q[0] = (argc == 2) ? argv[1] : "pzzpg""cc  g""ccllm""phhpm";q[0].p = -1;uint8_t a[10][2] __attribute__((aligned(32)));cpy20(a, q[0].aa);
#ifdef stAh Set_insert(&set, &u.n);
#elseAh set.insert(u.n);
#endifdouble tm = clock();for (; qh < qt; qh++) {if (q[qh].CCY == 3) { print_path(); break; }cpy20(a, q[qh].aa);uint8_t b[5][4] __attribute__((aligned(32))), overflow[12];_mm256_store_si256((__m256i*)b, _mm256_set1_epi8(1));set2DArrayByCoordInA(a, b, 0)int qt1 = qt;for (int j = 0; j < 4; j++) {int ok;for (int i = 0; i < 6; i++) {const int ox = a[i][1], oy = a[i][0];int x = (a[i][1] += D[j][0]), y = (a[i][0] += D[j][1]);if (x < 0 || x + W[i] > 4 || y < 0 || y + H[i] > 5) ok = 0;else { // D[]的顺序不能换!if (j == 0) { y = oy + H[i]; ok = b[y][x] && (W[i] == 1 || b[y][x + 1]); }else if (j == 1) ok = b[y][x] & (!(W[i] - 1) | b[y][x + 1]); // W[i]1或2; 不更快else if (j == 2) ok = b[y][x] & (!(H[i] - 1) | b[y + 1][x]);else { x = ox + W[i]; ok = b[y][x] && (H[i] == 1 || b[y + 1][x]); }}if_ok_add_statea[i][1] -= D[j][0]; a[i][0] -= D[j][1];}for (int i = 6; i < 10; i++) {const int ox = a[i][1], oy = a[i][0];int x = (a[i][1] += D[j][0]), y = (a[i][0] += D[j][1]);if (x < 0 || x + W[i] > 4 || y < 0 || y + H[i] > 5) ok = 0;else {if (j == 0) y = oy + H[i];else if (j == 3) x = ox + W[i];ok = b[y][x];}if_ok_add_statea[i][1] -= D[j][0]; a[i][0] -= D[j][1];}}
#if 1int qt2 = qt - 1;if (qt2 > qt1 && q[qt2].CCY < q[qt1].CCY) { State t = q[qt1]; q[qt1] = q[qt2]; q[qt2] = t; }
#endif}printf("%.6f %d\n", (clock() - tm) / CLOCKS_PER_SEC, qt);return 0;
}

 

 

ttt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/947201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sparkle签名检查绕过漏洞分析

本文详细分析了CVE-2025-0509安全漏洞,该漏洞存在于Sparkle更新框架2.6.4之前版本,攻击者能够绕过(Ed)DSA签名检查替换已签名的更新包,构成高风险安全威胁。Sparkle签名检查绕过漏洞分析 漏洞概述 CVE-2025-0509是一…

openEuler安装Oracle踩坑

不得不说Oracle安装在Windows上就够麻烦了,到Linux上直接地狱难度. 众所周知Oracle是收费软件,所以什么从仓库一键安装就不要想了, 现在更是变本加厉,下载必须注册Oracle账号,希望大家以后都别用了吧,用"世界上最…

RPC ServiceModel.Grpc C#

RPC ServiceModel.Grpc C#RPC ServiceModel.Grpc C# 在 DogWatcher 和 HeartbeatService 中,CancellationToken 的核心作用是响应外部取消信号(如服务停止、客户端断开连接等),避免资源泄漏并确保程序优雅退出。…

通过onvif ptz 控制摄像头以及通过opencv 实时进行数据处理

通过onvif ptz 控制摄像头以及通过opencv 实时进行数据处理是一个简单玩法,主要是设计基于云边端的玩法,通过mediamtx 或者ffmpeg 对于边缘的视频进行处理,之后转发到其他流服务,之后云端或者边缘服务通过通过openc…

【GitHub每日速递 251027】14.3k star! 告别AI开发痛点!Parlant让大模型指令遵循不再是难题

原文:https://mp.weixin.qq.com/s/KjAS4gDjAzWtmHkBLoo64Q 告别AI开发痛点!Parlant让大模型指令遵循不再是难题 parlant 是一个专注于控制能力的LLM代理工具。简单讲,它让大语言模型像智能助手一样执行实际任务,快速…

百天打卡

腰悬长剑 ,阔步长安// run new Vue({el: #app,data: {habits: [{day: 01,streak: 1,time: 2025-10-27 07:51}]} })#app { margin: 0 auto; padding: 16px 0; background: rgba(255, 255, 255, 1); font-family: "…

dataGridView 控件表格颜色交替设置

某些人和事,哪怕是路边的风景,可是只要看一眼,依然会让人觉得很美好。第一步:找到控件属性 DefaultCellStyle点击进去之后 ,选择颜色:第二步:找到AlternatingRowsDefault 属性点击进去之后选择颜色

2025年10月洗地机产品推荐榜:价格与性能全面对比

家里地板一天不擦就显灰,宠物掉毛、孩子洒汤、鞋底带沙,传统拖把来回换水腰酸背疼,吸尘器加拖把又占地方。想一次搞定“吸拖洗”,又怕滚刷缠发、污水发臭、机器太重推不动,更怕花几千元买回家却闲置。2025年洗地机…

北の独自升级

少年当时的醉话酒话是:齐先生,我想明白了,对世界不要失去期望,除了必须要好好活着之外,其实还有一层意思,就是当我们对这个世界给予善意后,如果非但没有得到善意的回报,甚至仅有恶意,这个时候,能够不失望,才…

读AI赋能11自由认知

读AI赋能11自由认知1. 互联网 1.1. 超链接地图1.1.1. 整合全球信息,使人人受益1.1.2. 互联网的设计初衷是抵御单点故障—这一特性也使其高度抗拒单一权威机构1.2. 依赖于技术协议而非国家法律来运作,更看重网络的弹性…

spring中常见的两种代理模式

🌿 Spring 中的两种常见代理模式 Spring AOP(面向切面编程)在底层主要通过 两种代理方式 来实现:代理方式依赖机制特点适用场景JDK 动态代理 java.lang.reflect.Proxy 只能代理 接口 Bean 实现了接口时,默认使用…

在AI技术唾手可得的时代,挖掘新需求成为核心竞争力——某知名数字货币钱包需求洞察

本文基于某知名数字货币钱包项目的技术文档和用户反馈数据,深入分析了该应用的核心功能特性和使用方式,并从中识别出用户提出的关键功能改进建议,为产品迭代提供重要参考。a.内容描述核心功能定位:该项目是一款独立…

What versions of Python still work in Windows XP?

python 3.4.4 https://www.python.org/downloads/release/python-344/I found that Python 2.7.9 and Python 3.4.4 are the newest versions of Python that work in Windows XP. I found this out through trial and…

SAM2 图像分割(3)鼠标选择多框 摄像头实时分割显示 - MKT

SAM2 图像分割(3)鼠标选择多框 摄像头实时分割显示 import cv2 import torch import time import numpy as np import os import sysimport sys sys.path.append(/home/r9000k/v2_project/v5_samyolo/2分割/sam2-mai…

Python 内存管理机制与垃圾回收技术解析

在 Python 编程中,开发者通常无需手动分配和释放内存,这一便利得益于 Python 强大的自动内存管理机制。作为程序运行的基础环节,内存管理直接关系到应用性能与稳定性。Python 通过精妙设计的内存管理架构与多层次垃…

随想随说

随想随说原来打破垄断, 也可以从利用垄断技术开始, 至于垄断技术是否愿意, 不是我的事了,我轻松了 哈哈,这个洞察非常犀利,堪称 “四两拨千斤”的破局智慧!这确实是一种高级的战略思维: “我不需要重新发明轮子…

Semantic-SSAM 是“一切多细都行,还能给标签”​​ - MKT

Semantic-SSAM 是“一切多细都行,还能给标签”​​Semantic-SSAM 是“一切多细都行,还能给标签”​​ https://github.com/UX-Decoder/Semantic-SAM

在windows10系统上运行第一个SDL3项目

使用的是SDL3-mingw https://github.com/libsdl-org/SDL/releases/tag/release-3.2.24 上面这个页面,选择下载SDL3-devel-3.2.24-mingw.zip,解压后复制x86_64-w64-mingw32这个目录到你的项目文件夹里,我的是sdl3_st…

传统AI模型的垄断壁垒与价值对话范式的演进:一项基于AI元人文构想的博弈格局与路径探析

传统AI模型的垄断壁垒与价值对话范式的演进:一项基于AI元人文构想的博弈格局与路径探析 一、转型背景与博弈格局传统AI模型的现状特征 当前人工智能领域呈现出显著的寡头垄断格局。在技术层面,OpenAI、Google、Meta、…

搞跨端渲染?你绕不开的HarfBuzz原理

搞跨端渲染?你绕不开的HarfBuzz原理本文是HarfBuzz系列的第二篇:本文概述一、关键概念与结构 1.1 script HarfBuzz 中 script 指的是文字系统的类型,注意不是指语言,不同语言也可能属于同一类书写系统,比如:hb_s…