CF1065D Three Pieces
题目描述:给出一个n*n的棋盘,棋盘上每个格子有一个值。你有一个子,要求将这个子从1移到n*n(去k时可以经过比k大的点)。
开局时它可以作为车,马,相(国际象棋)。每走一步耗费时间1。你也可以中途将它换为车,马,相(国际象棋),耗费时间1。
求最短时间,以及保证最短时间的最少替换次数。
题解:
一道恶心人的搜索题。对于每个点分为n*n*3种状态,表示当前已经经过1 ~ k,当前是车 / 马 / 相。
对于每个状态讨论做车 / 马 / 相怎么走,以及将它换成另外两种的情况。
代码(已经不想再写一遍了):
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 15
int n,mp[N][N],rx,ry,lx,ly;
int dis[N][N][N*N][],f[N][N][N*N][];
bool vis[N][N][N*N][];
struct node
{
int x,y,d,typ;
node(){}
node(int x,int y,int d,int typ):x(x),y(y),d(d),typ(typ){}
}tp;
queue<node>q;
int dx[]={-,-,-,-,,,,};
int dy[]={-,,-,,-,,-,};
void ins(int x,int y,int d,int t)
{
if(!vis[x][y][d][t])
{
vis[x][y][d][t]=;
q.push(node(x,y,d,t));
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
for(int j=;j<n;j++)
{
scanf("%d",&mp[i][j]);
if(mp[i][j]==)
{
rx=i,ry=j;
}else if(mp[i][j]==n*n)
{
lx=i,ly=j;
}
}
}
memset(dis,0x3f,sizeof dis);
memset(f,0x3f,sizeof f);
dis[rx][ry][][]=dis[rx][ry][][]=dis[rx][ry][][]=;
f[rx][ry][][]=f[rx][ry][][]=f[rx][ry][][]=;
q.push(node(rx,ry,,));q.push(node(rx,ry,,));q.push(node(rx,ry,,));
vis[rx][ry][][]=vis[rx][ry][][]=vis[rx][ry][][]=;
int x,y,d,t,tx,ty,dd;
while(!q.empty())
{
tp=q.front();
q.pop();
x=tp.x,y=tp.y,d=tp.d,t=tp.typ;
vis[x][y][d][t]=;
if(t==)
{
for(int i=;i<n;i++)
{
dd = d+(mp[i][y]==d+);
if(dis[i][y][dd][t]>dis[x][y][d][t]+)
{
dis[i][y][dd][t]=dis[x][y][d][t]+;
f[i][y][dd][t]=f[x][y][d][t];
ins(i,y,dd,t);
}else if(dis[i][y][dd][t]==dis[x][y][d][t]+)
{
if(f[i][y][dd][t]>f[x][y][d][t])
{
f[i][y][dd][t]=f[x][y][d][t];
ins(i,y,dd,t);
}
}
dd = d+(mp[x][i]==d+);
if(dis[x][i][dd][t]>dis[x][y][d][t]+)
{
dis[x][i][dd][t]=dis[x][y][d][t]+;
f[x][i][dd][t]=f[x][y][d][t];
ins(x,i,dd,t);
}else if(dis[x][i][dd][t]==dis[x][y][d][t]+)
{
if(f[x][i][dd][t]>f[x][y][d][t])
{
f[x][i][dd][t]=f[x][y][d][t];
ins(x,i,dd,t);
}
}
}
if(dis[x][y][d][]>dis[x][y][d][]+)
{
dis[x][y][d][]=dis[x][y][d][]+;
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}else if(dis[x][y][d][]==dis[x][y][d][]+)
{
if(f[x][y][d][]>f[x][y][d][]+)
{
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}
}
if(dis[x][y][d][]>dis[x][y][d][]+)
{
dis[x][y][d][]=dis[x][y][d][]+;
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}else if(dis[x][y][d][]==dis[x][y][d][]+)
{
if(f[x][y][d][]>f[x][y][d][]+)
{
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}
}
}else if(t==)
{
for(int i=;i<;i++)
{
tx = x+dx[i],ty = y+dy[i];
if(tx<||ty<||tx>=n||ty>=n)continue;
dd = d+(mp[tx][ty]==d+);
if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
{
dis[tx][ty][dd][t]=dis[x][y][d][t]+;
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
{
if(f[tx][ty][dd][t]>f[x][y][d][t])
{
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}
}
}
if(dis[x][y][d][]>dis[x][y][d][]+)
{
dis[x][y][d][]=dis[x][y][d][]+;
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}else if(dis[x][y][d][]==dis[x][y][d][]+)
{
if(f[x][y][d][]>f[x][y][d][]+)
{
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}
}
if(dis[x][y][d][]>dis[x][y][d][]+)
{
dis[x][y][d][]=dis[x][y][d][]+;
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}else if(dis[x][y][d][]==dis[x][y][d][]+)
{
if(f[x][y][d][]>f[x][y][d][]+)
{
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}
}
}else
{
for(int i=;x-i>=&&y-i>=;i++)
{
tx = x-i,ty = y-i;
dd = d+(mp[tx][ty]==d+);
if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
{
dis[tx][ty][dd][t]=dis[x][y][d][t]+;
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
{
if(f[tx][ty][dd][t]>f[x][y][d][t])
{
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}
}
}
for(int i=;x+i<n&&y-i>=;i++)
{
tx = x+i,ty = y-i;
dd = d+(mp[tx][ty]==d+);
if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
{
dis[tx][ty][dd][t]=dis[x][y][d][t]+;
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
{
if(f[tx][ty][dd][t]>f[x][y][d][t])
{
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}
}
}
for(int i=;x-i>=&&y+i<n;i++)
{
tx = x-i,ty = y+i;
dd = d+(mp[tx][ty]==d+);
if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
{
dis[tx][ty][dd][t]=dis[x][y][d][t]+;
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
{
if(f[tx][ty][dd][t]>f[x][y][d][t])
{
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}
}
}
for(int i=;x+i<n&&y+i<n;i++)
{
tx = x+i,ty = y+i;
dd = d+(mp[tx][ty]==d+);
if(dis[tx][ty][dd][t]>dis[x][y][d][t]+)
{
dis[tx][ty][dd][t]=dis[x][y][d][t]+;
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+)
{
if(f[tx][ty][dd][t]>f[x][y][d][t])
{
f[tx][ty][dd][t]=f[x][y][d][t];
ins(tx,ty,dd,t);
}
}
}
if(dis[x][y][d][]>dis[x][y][d][]+)
{
dis[x][y][d][]=dis[x][y][d][]+;
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}else if(dis[x][y][d][]==dis[x][y][d][]+)
{
if(f[x][y][d][]>f[x][y][d][]+)
{
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}
}
if(dis[x][y][d][]>dis[x][y][d][]+)
{
dis[x][y][d][]=dis[x][y][d][]+;
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}else if(dis[x][y][d][]==dis[x][y][d][]+)
{
if(f[x][y][d][]>f[x][y][d][]+)
{
f[x][y][d][]=f[x][y][d][]+;
ins(x,y,d,);
}
}
}
}
int ans = dis[lx][ly][n*n][],tk=f[lx][ly][n*n][];
if(dis[lx][ly][n*n][]<ans)
{
ans=dis[lx][ly][n*n][];
tk =f[lx][ly][n*n][];
}else if(dis[lx][ly][n*n][]==ans)
{
tk=min(tk,f[lx][ly][n*n][]);
}
if(dis[lx][ly][n*n][]<ans)
{
ans=dis[lx][ly][n*n][];
tk =f[lx][ly][n*n][];
}else if(dis[lx][ly][n*n][]==ans)
{
tk=min(tk,f[lx][ly][n*n][]);
}
printf("%d %d\n",ans,tk);
return ;
}
CF1065D Three Pieces的更多相关文章
- CF1065D Three Pieces (多元最短路)
题目大意:给你一个棋盘,你需要控制棋子依次经过编号为1~n的所有点,棋子的可以是车,马,象,都依照国际象棋的行棋方式,每走一步消耗1单位时间,但每次更换棋子都需要额外1单位时间,求经过所有点需要的最少 ...
- HITOJ 2662 Pieces Assignment(状压DP)
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- 1.4.8 拼凑在一起(putting the pieces together)
putting the pieces together 在最高的级别,schema.xml结构如下, <schema> <types> <fields> <u ...
- uva 12296 Pieces and Discs
题意: 有个矩形,左下角(0,0),左上角(L,W). 思路: 除了圆盘之外,本题的输入也是个PSLG,因此可以按照前面叙述的算法求出各个区域:只需把线段视为直线,用切割凸多边形的方法 :每次读入线段 ...
- Pizza pieces
Pizza pieces Description In her trip to Italy, Elizabeth Gilbert made it her duty to eat perfect piz ...
- HDU 4628 Pieces(DP + 状态压缩)
Pieces 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628 题目大意:给定一个字符串s,如果子序列中有回文,可以一步删除掉它,求把整个序列删除 ...
- 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 ...
- 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 ...
- hdu 4628 Pieces 状态压缩dp
Pieces Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total S ...
随机推荐
- [SDOI2019] 移动金币
分析 阶梯NIM模型:共有m+1堆石子,石子总数不超过n-m,求必胜的,即奇数堆石子数目异或和非零的局面数.补集转化,答案C(n,m)-奇数堆石子数目异或和位0的局面数. 可以想到按位dp,设f[i, ...
- Python unittest 基本框架解析(2)
下面例子,是一般测试框架的基本结构 框架知识点包括:实例化被测试模块类.装载测试用例.测试套件打包.保存测试输出结果.生成测试报告等 测试情况包括 :跳过某个case.执行成功.执行失败 #待测试 ...
- LightOj 1236 Pairs Forming LCM (素数筛选&&唯一分解定理)
题目大意: 有一个数n,满足lcm(i,j)==n并且i<=j时,(i,j)有多少种情况? 解题思路: n可以表示为:n=p1^x1*p2^x1.....pk^xk. 假设lcm(a,b) == ...
- bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作
2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ...
- 贪心+模拟 ZOJ 3829 Known Notation
题目传送门 /* 题意:一串字符串,问要最少操作数使得成为合法的后缀表达式 贪心+模拟:数字个数 >= *个数+1 所以若数字少了先补上在前面,然后把不合法的*和最后的数字交换,记录次数 岛娘的 ...
- C#内存映射文件学习[转]
原文链接 内存映射文件是由一个文件到进程地址空间的映射. C#提供了允许应用程序把文件映射到一个进程的函(MemoryMappedFile.CreateOrOpen).内存映射文件与虚拟内存有些类似, ...
- 【转载】WebConfigurationManager和ConfigurationManager
原文链接 今天在写程序时偶然发现有的示例代码中是用WebConfigurationManager获取web.config中的配置信息的,因为之前一直都是用的ConfigurationManager,所 ...
- python vs java的rsa加密
首先:java的加密解密模块需要更加精细的算法细节指定 java的加密方式 javax.crypto.Cipher,定义的获取方式 tatic Cipher getInstance(String tr ...
- c语言-依赖倒转
当一个文件(aa.c文件)依赖于头文件(bb.h)时,如果bb.c编译之后形成的bb.o文件重新编译后,aa.o的文件不需要重新编译 aa.c文件: bb.h文件:对bb.c文件进行声明 bb.c文件 ...
- 【译】x86程序员手册34-9.7错误代码
9.7 Error Code 错误代码 With exceptions that relate to a specific segment, the processor pushes an error ...