题目描述:给出一个n*n的棋盘,棋盘上每个格子有一个值。你有一个子,要求将这个子从1移到n*n(去k时可以经过比k大的点)。

开局时它可以作为车,马,相(国际象棋)。每走一步耗费时间1。你也可以中途将它换为车,马,相(国际象棋),耗费时间1。

求最短时间,以及保证最短时间的最少替换次数。

题解:

一道恶心人的搜索题。对于每个点分为n*n*3种状态,表示当前已经经过1 ~ k,当前是车 / 马 / 相。

对于每个状态讨论做车 / 马 / 相怎么走,以及将它换成另外两种的情况。

代码(已经不想再写一遍了):

  1. #include<queue>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. #define N 15
  7. int n,mp[N][N],rx,ry,lx,ly;
  8. int dis[N][N][N*N][],f[N][N][N*N][];
  9. bool vis[N][N][N*N][];
  10. struct node
  11. {
  12. int x,y,d,typ;
  13. node(){}
  14. node(int x,int y,int d,int typ):x(x),y(y),d(d),typ(typ){}
  15. }tp;
  16. queue<node>q;
  17. int dx[]={-,-,-,-,,,,};
  18. int dy[]={-,,-,,-,,-,};
  19. void ins(int x,int y,int d,int t)
  20. {
  21. if(!vis[x][y][d][t])
  22. {
  23. vis[x][y][d][t]=;
  24. q.push(node(x,y,d,t));
  25. }
  26. }
  27. int main()
  28. {
  29. scanf("%d",&n);
  30. for(int i=;i<n;i++)
  31. {
  32. for(int j=;j<n;j++)
  33. {
  34. scanf("%d",&mp[i][j]);
  35. if(mp[i][j]==)
  36. {
  37. rx=i,ry=j;
  38. }else if(mp[i][j]==n*n)
  39. {
  40. lx=i,ly=j;
  41. }
  42. }
  43. }
  44. memset(dis,0x3f,sizeof dis);
  45. memset(f,0x3f,sizeof f);
  46. dis[rx][ry][][]=dis[rx][ry][][]=dis[rx][ry][][]=;
  47. f[rx][ry][][]=f[rx][ry][][]=f[rx][ry][][]=;
  48. q.push(node(rx,ry,,));q.push(node(rx,ry,,));q.push(node(rx,ry,,));
  49. vis[rx][ry][][]=vis[rx][ry][][]=vis[rx][ry][][]=;
  50. int x,y,d,t,tx,ty,dd;
  51. while(!q.empty())
  52. {
  53. tp=q.front();
  54. q.pop();
  55. x=tp.x,y=tp.y,d=tp.d,t=tp.typ;
  56. vis[x][y][d][t]=;
  57. if(t==)
  58. {
  59. for(int i=;i<n;i++)
  60. {
  61. dd = d+(mp[i][y]==d+);
  62. if(dis[i][y][dd][t]>dis[x][y][d][t]+)
  63. {
  64. dis[i][y][dd][t]=dis[x][y][d][t]+;
  65. f[i][y][dd][t]=f[x][y][d][t];
  66. ins(i,y,dd,t);
  67. }else if(dis[i][y][dd][t]==dis[x][y][d][t]+)
  68. {
  69. if(f[i][y][dd][t]>f[x][y][d][t])
  70. {
  71. f[i][y][dd][t]=f[x][y][d][t];
  72. ins(i,y,dd,t);
  73. }
  74. }
  75. dd = d+(mp[x][i]==d+);
  76. if(dis[x][i][dd][t]>dis[x][y][d][t]+)
  77. {
  78. dis[x][i][dd][t]=dis[x][y][d][t]+;
  79. f[x][i][dd][t]=f[x][y][d][t];
  80. ins(x,i,dd,t);
  81. }else if(dis[x][i][dd][t]==dis[x][y][d][t]+)
  82. {
  83. if(f[x][i][dd][t]>f[x][y][d][t])
  84. {
  85. f[x][i][dd][t]=f[x][y][d][t];
  86. ins(x,i,dd,t);
  87. }
  88. }
  89. }
  90. if(dis[x][y][d][]>dis[x][y][d][]+)
  91. {
  92. dis[x][y][d][]=dis[x][y][d][]+;
  93. f[x][y][d][]=f[x][y][d][]+;
  94. ins(x,y,d,);
  95. }else if(dis[x][y][d][]==dis[x][y][d][]+)
  96. {
  97. if(f[x][y][d][]>f[x][y][d][]+)
  98. {
  99. f[x][y][d][]=f[x][y][d][]+;
  100. ins(x,y,d,);
  101. }
  102. }
  103. if(dis[x][y][d][]>dis[x][y][d][]+)
  104. {
  105. dis[x][y][d][]=dis[x][y][d][]+;
  106. f[x][y][d][]=f[x][y][d][]+;
  107. ins(x,y,d,);
  108. }else if(dis[x][y][d][]==dis[x][y][d][]+)
  109. {
  110. if(f[x][y][d][]>f[x][y][d][]+)
  111. {
  112. f[x][y][d][]=f[x][y][d][]+;
  113. ins(x,y,d,);
  114. }
  115. }
  116. }else if(t==)
  117. {
  118. for(int i=;i<;i++)
  119. {
  120. tx = x+dx[i],ty = y+dy[i];
  121. if(tx<||ty<||tx>=n||ty>=n)continue;
  122. dd = d+(mp[tx][ty]==d+);
  123. if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
  124. {
  125. dis[tx][ty][dd][t]=dis[x][y][d][t]+;
  126. f[tx][ty][dd][t]=f[x][y][d][t];
  127. ins(tx,ty,dd,t);
  128. }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
  129. {
  130. if(f[tx][ty][dd][t]>f[x][y][d][t])
  131. {
  132. f[tx][ty][dd][t]=f[x][y][d][t];
  133. ins(tx,ty,dd,t);
  134. }
  135. }
  136. }
  137. if(dis[x][y][d][]>dis[x][y][d][]+)
  138. {
  139. dis[x][y][d][]=dis[x][y][d][]+;
  140. f[x][y][d][]=f[x][y][d][]+;
  141. ins(x,y,d,);
  142. }else if(dis[x][y][d][]==dis[x][y][d][]+)
  143. {
  144. if(f[x][y][d][]>f[x][y][d][]+)
  145. {
  146. f[x][y][d][]=f[x][y][d][]+;
  147. ins(x,y,d,);
  148. }
  149. }
  150. if(dis[x][y][d][]>dis[x][y][d][]+)
  151. {
  152. dis[x][y][d][]=dis[x][y][d][]+;
  153. f[x][y][d][]=f[x][y][d][]+;
  154. ins(x,y,d,);
  155. }else if(dis[x][y][d][]==dis[x][y][d][]+)
  156. {
  157. if(f[x][y][d][]>f[x][y][d][]+)
  158. {
  159. f[x][y][d][]=f[x][y][d][]+;
  160. ins(x,y,d,);
  161. }
  162. }
  163. }else
  164. {
  165. for(int i=;x-i>=&&y-i>=;i++)
  166. {
  167. tx = x-i,ty = y-i;
  168. dd = d+(mp[tx][ty]==d+);
  169. if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
  170. {
  171. dis[tx][ty][dd][t]=dis[x][y][d][t]+;
  172. f[tx][ty][dd][t]=f[x][y][d][t];
  173. ins(tx,ty,dd,t);
  174. }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
  175. {
  176. if(f[tx][ty][dd][t]>f[x][y][d][t])
  177. {
  178. f[tx][ty][dd][t]=f[x][y][d][t];
  179. ins(tx,ty,dd,t);
  180. }
  181. }
  182. }
  183. for(int i=;x+i<n&&y-i>=;i++)
  184. {
  185. tx = x+i,ty = y-i;
  186. dd = d+(mp[tx][ty]==d+);
  187. if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
  188. {
  189. dis[tx][ty][dd][t]=dis[x][y][d][t]+;
  190. f[tx][ty][dd][t]=f[x][y][d][t];
  191. ins(tx,ty,dd,t);
  192. }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
  193. {
  194. if(f[tx][ty][dd][t]>f[x][y][d][t])
  195. {
  196. f[tx][ty][dd][t]=f[x][y][d][t];
  197. ins(tx,ty,dd,t);
  198. }
  199. }
  200. }
  201. for(int i=;x-i>=&&y+i<n;i++)
  202. {
  203. tx = x-i,ty = y+i;
  204. dd = d+(mp[tx][ty]==d+);
  205. if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
  206. {
  207. dis[tx][ty][dd][t]=dis[x][y][d][t]+;
  208. f[tx][ty][dd][t]=f[x][y][d][t];
  209. ins(tx,ty,dd,t);
  210. }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
  211. {
  212. if(f[tx][ty][dd][t]>f[x][y][d][t])
  213. {
  214. f[tx][ty][dd][t]=f[x][y][d][t];
  215. ins(tx,ty,dd,t);
  216. }
  217. }
  218. }
  219. for(int i=;x+i<n&&y+i<n;i++)
  220. {
  221. tx = x+i,ty = y+i;
  222. dd = d+(mp[tx][ty]==d+);
  223. if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
  224. {
  225. dis[tx][ty][dd][t]=dis[x][y][d][t]+;
  226. f[tx][ty][dd][t]=f[x][y][d][t];
  227. ins(tx,ty,dd,t);
  228. }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
  229. {
  230. if(f[tx][ty][dd][t]>f[x][y][d][t])
  231. {
  232. f[tx][ty][dd][t]=f[x][y][d][t];
  233. ins(tx,ty,dd,t);
  234. }
  235. }
  236. }
  237. if(dis[x][y][d][]>dis[x][y][d][]+)
  238. {
  239. dis[x][y][d][]=dis[x][y][d][]+;
  240. f[x][y][d][]=f[x][y][d][]+;
  241. ins(x,y,d,);
  242. }else if(dis[x][y][d][]==dis[x][y][d][]+)
  243. {
  244. if(f[x][y][d][]>f[x][y][d][]+)
  245. {
  246. f[x][y][d][]=f[x][y][d][]+;
  247. ins(x,y,d,);
  248. }
  249. }
  250. if(dis[x][y][d][]>dis[x][y][d][]+)
  251. {
  252. dis[x][y][d][]=dis[x][y][d][]+;
  253. f[x][y][d][]=f[x][y][d][]+;
  254. ins(x,y,d,);
  255. }else if(dis[x][y][d][]==dis[x][y][d][]+)
  256. {
  257. if(f[x][y][d][]>f[x][y][d][]+)
  258. {
  259. f[x][y][d][]=f[x][y][d][]+;
  260. ins(x,y,d,);
  261. }
  262. }
  263. }
  264. }
  265. int ans = dis[lx][ly][n*n][],tk=f[lx][ly][n*n][];
  266. if(dis[lx][ly][n*n][]<ans)
  267. {
  268. ans=dis[lx][ly][n*n][];
  269. tk =f[lx][ly][n*n][];
  270. }else if(dis[lx][ly][n*n][]==ans)
  271. {
  272. tk=min(tk,f[lx][ly][n*n][]);
  273. }
  274. if(dis[lx][ly][n*n][]<ans)
  275. {
  276. ans=dis[lx][ly][n*n][];
  277. tk =f[lx][ly][n*n][];
  278. }else if(dis[lx][ly][n*n][]==ans)
  279. {
  280. tk=min(tk,f[lx][ly][n*n][]);
  281. }
  282. printf("%d %d\n",ans,tk);
  283. return ;
  284. }

CF1065D Three Pieces的更多相关文章

  1. CF1065D Three Pieces (多元最短路)

    题目大意:给你一个棋盘,你需要控制棋子依次经过编号为1~n的所有点,棋子的可以是车,马,象,都依照国际象棋的行棋方式,每走一步消耗1单位时间,但每次更换棋子都需要额外1单位时间,求经过所有点需要的最少 ...

  2. HITOJ 2662 Pieces Assignment(状压DP)

    Pieces Assignment My Tags   (Edit)   Source : zhouguyue   Time limit : 1 sec   Memory limit : 64 M S ...

  3. 1.4.8 拼凑在一起(putting the pieces together)

    putting the pieces together 在最高的级别,schema.xml结构如下, <schema> <types> <fields> <u ...

  4. uva 12296 Pieces and Discs

    题意: 有个矩形,左下角(0,0),左上角(L,W). 思路: 除了圆盘之外,本题的输入也是个PSLG,因此可以按照前面叙述的算法求出各个区域:只需把线段视为直线,用切割凸多边形的方法 :每次读入线段 ...

  5. Pizza pieces

    Pizza pieces Description In her trip to Italy, Elizabeth Gilbert made it her duty to eat perfect piz ...

  6. HDU 4628 Pieces(DP + 状态压缩)

    Pieces 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628 题目大意:给定一个字符串s,如果子序列中有回文,可以一步删除掉它,求把整个序列删除 ...

  7. Codeforces 328B-Sheldon and Ice Pieces(馋)

    B. Sheldon and Ice Pieces time limit per test 1 second memory limit per test 256 megabytes input sta ...

  8. 2017 NAIPC A:Pieces of Parentheses

    my team solve the problem in the contest with similar ideathis is a more deep analysis The main idea ...

  9. hdu 4628 Pieces 状态压缩dp

    Pieces Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

随机推荐

  1. Rails 浅谈 ActiveRecord 的 N + 1 查询问题(copy)

    [说明:资料来自https://ruby-china.org/topics/32364] ORM框架的性能小坑 在使用ActiveRecord这样的ORM工具时,常会嵌套遍历model.例如,有两个m ...

  2. win10下的jdk1.8安装

    1 下载jdk 下一步就好 默认C盘最好 不要又中文  http://pan.baidu.com/s/1eSwvFA6(这里面有两个jdk 32位 64位) 看图 CLASSPATH: .;%JAVA ...

  3. TS数据流PAT和PMT分析(转载)

    转自:http://www.cnblogs.com/hjj801006/p/3837435.html TS流,是基于packet的位流格式,每个packet是188个字节或者204个字 节(一般是18 ...

  4. 在Centos中yum安装和卸载软件的使用方法(转载)

    转自: http://gzmaster.blog.51cto.com/299556/72278 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任. ...

  5. 安装 Spring 框架库

    下载地址:http://repo.spring.io/release/org/springframework/spring

  6. [ZPG TEST 110] 多边形个数【DP】

    1. 多边形个数 (polygons.pas/c/cpp) [问题描述] 给定N线段,编号1到n.并给出这些线段的长度,用这些线段组成一个K边形,并且每个线段做多使用一次.若使用了一条不同编号的线段, ...

  7. (转)C语言运算符优先级 详细列表

    C语言运算符优先级 详细列表 文章转自:Slyar Home 优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右   () 圆括号 (表达式)/函数 ...

  8. urllib的高级用法

    Handler简介 我们可以把他理解为各种处理器,有专门处理登录验证的,有处理cookies的,有处理代理设置的.利用他们,我们几乎可以做到HTTP请求中的所有事情. 首先,介绍一下 urllib.r ...

  9. java数组实现买彩票(阿基老师的打乱排序思想)

    package com.wh.array; public class Lottery { public static void main(String[] args) { int[] num=new ...

  10. 456 132 Pattern 132模式

    给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj.设计一个算法,当 ...