[A*] HDU 1043
来源:互联网 发布:电脑连上网却没有网络 编辑:程序博客网 时间:2024/06/06 02:51
虽然是过了
但因为一开始hash值存在结构体里所以TLE
下次还是打表吧
#include <algorithm>#include <iostream>#include <math.h>#include <queue>#include <stack>#include <stdio.h>#include <string.h>using namespace std;struct Node { char map[ 3 ][ 3 ]; int x, y; int g, h; // g是已经走过的步数,h是剩下距离终点的距离 bool operator< ( const Node t ) const { return h + g > t.h + t.g; }} cur, nex;char str[ 100 ];int check_rev () //逆序数对,判断不可能的状况{ int i, j, k; int s[ 20 ]; int cnt = 0; for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { s[ 3 * i + j ] = cur.map[ i ][ j ]; if ( s[ 3 * i + j ] == 'x' ) continue; for ( k = 3 * i + j - 1; k >= 0; k-- ) { if ( s[ k ] == 'x' ) continue; if ( s[ k ] > s[ 3 * i + j ] ) cnt++; } } } if ( cnt % 2 ) return 0; return 1;}//康托展开 0~8的阶乘int factorial[ 9 ] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};int get_hash ( Node a ) //康托{ int i, j, k; int s[ 20 ]; int ans = 0; for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { s[ 3 * i + j ] = a.map[ i ][ j ]; int cnt = 0; for ( k = 3 * i + j - 1; k >= 0; k-- ) { if ( s[ k ] > s[ 3 * i + j ] ) cnt++; } ans = ans + factorial[ i * 3 + j ] * cnt; } } return ans;}// 3*3每个点的indxint pos[][ 2 ] = {{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}};int get_h ( Node a ) //得到距离终点距离的值{ int i, j; int ans = 0; for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { if ( a.map[ i ][ j ] == 'x' ) continue; int k = a.map[ i ][ j ] - '1'; ans += abs ( pos[ k ][ 0 ] - i ) + abs ( pos[ k ][ 1 ] - j ); } } return ans;}//判断是否出界inline bool path ( int x, int y ) { if ( x >= 0 && x < 3 && y >= 0 && y < 3 ) return true; return false;}bool vis[ 500000 ];int dir[ 4 ][ 2 ] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};//回溯用char ch[ 500000 ];int pre[ 500000 ];char way[ 10 ] = "drul";void A_star () { memset ( vis, 0, sizeof ( vis ) ); cur.g = 0; cur.h = get_h ( cur ); priority_queue<Node> Q; Q.push ( cur ); while ( !Q.empty () ) { Node a = Q.top (); Q.pop (); int k_s = get_hash ( a ); for ( int i = 0; i < 4; i++ ) { nex = a; nex.x += dir[ i ][ 0 ]; nex.y += dir[ i ][ 1 ]; if ( path ( nex.x, nex.y ) ) { // swap nex.map[ a.x ][ a.y ] = a.map[ nex.x ][ nex.y ]; nex.map[ nex.x ][ nex.y ] = 'x'; nex.g += 1; nex.h = get_h ( nex ); //找个变量存一下( 存在结构体里会TLE ) int k_n = get_hash ( nex ); if ( !vis[ k_n ] ) { vis[ k_n ] = true; Q.push ( nex ); pre[ k_n ] = k_s; ch[ k_n ] = way[ i ]; if ( k_n == 0 ) return; } } } }}int main () { int i, len, x, y; //输入 while ( cin.getline ( str, 100 ) ) { x = y = 0; len = strlen ( str ); for ( i = 0; i < len; i++ ) { if ( ( str[ i ] >= '0' && str[ i ] <= '9' ) || str[ i ] == 'x' ) { cur.map[ x ][ y ] = str[ i ]; if ( cur.map[ x ][ y ] == 'x' ) { cur.x = x; cur.y = y; } y++; if ( y == 3 ) { y = 0; x++; } } } //判断逆序对数,能否转换成最后结果 if ( !check_rev () ) { printf ( "unsolvable\n" ); continue; } int sa = get_hash ( cur ); A_star (); //输出 stack<char> s; int now = 0; while ( sa != now ) { s.push ( ch[ now ] ); now = pre[ now ]; } while ( !s.empty () ) { putchar ( s.top () ); s.pop (); } printf ( "\n" ); } return 0;}
阅读全文
0 0
- hdu 1043 A*
- hdu 1043 eight a*
- hdu 1043 Eight(A*)
- [A*] HDU 1043
- hdu 1043 八数码 A*
- HDU-1043 Eight(A*)
- HDU 1043 搜索 A*算法
- HDU 1043 八数码问题 A*搜索
- HDU 1043 八数码问题 A*搜索
- 八数码A*【POJ-1077 HDU-1043】
- hdu 1043 Eight 双向BFS/A*算法
- HDU 1043 A*与康托
- [HDU 1043] Eight A*或IDA*
- HDU 1043 八数码(A*搜索)
- HDU 1043 && POJ 1077 Eight (A*)
- hdu 1043 八数码问题-A*搜索
- Tr A hdu 1575
- HDU Problem A
- 2017.11.08 周三 Linux中的一些常用工具
- HTML基础(一)
- bzoj 2208 [Jsoi2010]连通数 bitset
- sqlserver2008评估期已过,有关如何升级您的测试版软件的信息,请访问
- 数据库引擎
- [A*] HDU 1043
- CCF考试——201604-1折点计数
- 项目页
- Linux中Ls命令的使用
- 学会利用java编写学生信息
- 使用maven创建java项目
- IP,TCP,UDP,ICMP校验和的区别和计算
- mysql学习笔记
- HTTP和HTTPS对比区别