首页 > 其他分享 >HDU 1404 ”Solitaire“ (双向广搜)

HDU 1404 ”Solitaire“ (双向广搜)

时间:2023-12-26 16:11:22浏览次数:33  
标签:HDU return int head next ++ Solitaire str 1404

HDU 1404 ”Solitaire"

OJ:https://acm.hdu.edu.cn/showproblem.php?pid=1401
题目大意:8 * 8 的棋盘,上面有四个棋子,棋子可以上下左右移动,如果在上下左右移动的时候该位置有一个棋子已经放置,可以跳过这个棋子放在后面,不可以连续跳过两个。给一个初始状态和一个目标状态。是否可以在八步之内让初始状态达到目标状态

输入 每排每两个数字代表一个棋子坐标,每排一共四个坐标

4 4 4 5 5 4 6 5
2 4 3 3 3 6 4 6

输出 YES/NO

YES

思路 :
一、用BFS暴力搜索,问题主要是怎么存储每个状态棋子的位置。每个棋子拥有x,y两个坐标数据,目前还不会使用map,就用思维数组vir[64][64][64][64]来储存,虽然占用的内存有点大
二、用双向广度搜索优化BFS,减少搜索次数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include <algorithm>
using namespace std;
char virs[64][64][64][64] = { '\0'};//记录正向和反向已经到达的状态
int dir[4][2] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} };//移动的四个方向
struct node {
	int state[4];
	int step;
};
//检查另一个方向是否到达过,并对当前状态排序
int visited(int* str,char flag) {
	sort(str, str + 4);
	if (!virs[str[0]][str[1]][str[2]][str[3]]) {
		virs[str[0]][str[1]][str[2]][str[3]] = flag;
		return 0;
	}
	if (flag == virs[str[0]][str[1]][str[2]][str[3]]) return 0;
	else return 1;
}
//检查是否可以移动或者跳棋,如果可以移动并返回true
bool is_move(int* str, int i, int n) {
	int x = str[i] % 8;
	int y = str[i] / 8;
	x = x + dir[n][0];
	y = y + dir[n][1];
	if (x < 0 || x >= 8 || y < 0 || y >= 8) return false;
	for (int j = 0; j < 4; j++) {
		if (x + y * 8 == str[j]) {
			x = x + dir[n][0];
			y = y + dir[n][1];
			for (int m = 0; m < 4; m++) {
				if (x + y * 8 == str[m] || x < 0 || x >= 8 || y < 0 || y >= 8) return false;
			}
		}
	}
	str[i] = x + y * 8;
	return true;
}
int start[4];
int goal[4];
//双向bfs
int bfs() {
	memset(virs, '\0', sizeof(virs));
	queue <node> q1, q2;
	node head, next;
	memcpy(head.state, start, sizeof(start));
	head.step = 0;
	if (visited(head.state, '1')) return 1;
	q1.push(head);
	memcpy(head.state, goal, sizeof(goal));
	head.step = 0;
	if (visited(head.state, '2')) return 1;
	q2.push(head);
	while (!q1.empty() || !q2.empty()) {
		if (!q1.empty()) {
			head = q1.front();
			q1.pop();
			if (head.step >= 4) continue;//弹空队列
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 4; j++) {
					next = head;
					next.step++;
					if (!is_move(next.state, i, j)) continue;
					if (visited(next.state, '1')) return 1;
					q1.push(next);
				}
			}
		}
		if (!q2.empty()) {
			head = q2.front();
			q2.pop();
			if (head.step >= 4) continue;//弹空队列
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 4; j++) {
					next = head;
					next.step++;
					if (!is_move(next.state, i, j)) continue;
					if (visited(next.state, '2')) return 1;
					q2.push(next);
				}
			}
		}
	}
	return 0;
}
int main() {
	int r, c;
	while (~scanf("%d%d", &r, &c)) {
		memset(start, 0, sizeof(start));
		memset(goal, 0, sizeof(goal));
		start[0] = (r - 1) * 8 + (c - 1);
		for (int i = 1; i < 4; i++) {
			scanf("%d%d", &r, &c);
			start[i] = (r - 1) * 8 + (c - 1);
		}
		for (int i = 0; i < 4; i++) {
			scanf("%d%d", &r, &c);
			goal[i] = (r - 1) * 8 + (c - 1);
		}
		int ans = bfs();
		printf("%s\n", ans ? "YES" : "NO");
	}
	
	return 0;
}

标签:HDU,return,int,head,next,++,Solitaire,str,1404
From: https://www.cnblogs.com/zhclovemyh/p/17928359.html

相关文章

  • 2023-2024 20231404高伟光《计算机基础与程序设计》第十三周学习总结
    作业信息作业内容我的班级我的班级作业要求第十三周要求作业目标学习c语言中结构体和基础的数据结构作业正文此博客教材内容总结c语言程序设计第十二章中主要讲了结构体的定义,使用方法还有结构体指针的相关用法.以结构体为基础,衍生讲了联合体和枚......
  • 2023-2024 20231404高伟光《计算机基础与程序设计》第十二周学习总结
    作业信息作业内容我的班级我的班级作业要求第十二周要求作业目标学习c语言中结构体和基础的数据结构作业正文此博客教材内容总结c语言程序设计第十二章中主要讲了结构体的定义,使用方法还有结构体指针的相关用法.以结构体为基础,衍生讲了联合体和枚......
  • 2023-2024 20231404高伟光《计算机基础与程序设计》第十周学习总结
    作业信息作业内容我的班级我的班级作业要求第九周要求作业目标信息系统,数据库与SQL,人工智能与专家系统,人工神经网络,模拟与离散事件,排队系统,天气与地震模型,图形图像作业正文此博客教材内容总结c语言程序设计课本第九章初步引入了指针的介绍.......
  • FlashDuty Changelog 2023-10-30 | 告警路由与 Slack 应用
    FlashDuty:一站式告警响应平台,前往此地址免费体验!告警路由什么是告警路由?FlashDuty已经与Zabbix、Prometheus等监控系统实现无缝集成,通过一个简单的webhook就可以把告警系统产生的所有告警事件推送到FlashDuty来管理。每个告警事件的重要性、紧急程度和所属团队可能不同,我们期望可以......
  • 2023-2024 20231404高伟光《计算机基础与程序设计》第九周学习总结
    作业信息作业内容我的班级我的班级作业要求第八周要求作业目标操作系统责任,内存与进程管理,分时系统,CPU调度,文件、文件系统,文件保护,磁盘调度作业正文此博客教材内容总结c语言程序设计第八章介绍了数组的一系列用法定义,介绍了经典的排序和查找算法,比......
  • 【HDU 1276】士兵队列训练问题 题解(链表+模拟)
    某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至......
  • 2023-2024 20231404高伟光《计算机基础与程序设计》第七周学习总结
    作业信息作业班级23级14班作业要求第七周要求作业目标自主学习计算机概论第八章,学习c语言第六章作业正文此博客教材内容总结计算机概论:应用层涉及了数据结构,本章介绍了栈(先进后出),队列(先进先出),列表(线性,无线),树,二叉树(每个节点只有一个父母节点,两个子节点),二......
  • HDU7401 流量监控
    给定一颗\(n\)个节点的树。求:有多少种匹配\((a_1,b_{1}),\cdots,(a_{\frac{n}{2}},b_{\frac{n}{2}})\),使得对于每一对匹配\((u,v)\),点\(u\)是点\(v\)的祖先。对于一组合法匹配,定义其权值为这些匹配的交点个数。对于两组匹配\((a,b),(c,d)\),它们之间有一个交点当且仅当......
  • ARC_068F Solitaire题解
    非常骚的一道题首先看数据范围就很像dp(而且在dp专题里),尝试直接dp,发现不太行手玩一波样例,发现答案是2的若干次方乘一个系数。我们发现“若干”=n-k-1,这是巧合吗!?思索一番,会发现当我们取完k个数后剩下的n-k个数取法就为2^(n-k-1),为什么呢?可以把每次操作看成“前取“”or......
  • 2023-2024-1 20231404高伟光《计算机基础与程序设计》第六周学习总结
    作业信息这个作业属于哪个课程2314班计算机作业要求2023-2024-1计算机基础与程序设计第6周作业作业目标自学教材计算机科学概论第7章《C语言程序设计》第5章作业正文此博客教材学习内容总结较详细的介绍了伪代码,解决问题的基本步骤。用伪代码讲述了搜索......