【USACO题库】3.3.3 Camelot亚瑟王的宫殿
2016-04-16 16:26
375 查看
亚瑟王的宫殿这一道题目其实是IOI 1998年的第4道题目,所以应该还是有一定难度的,凭借自己的实力做了出来,还是非常开心的,我的方法如下:
因为题目描述不清楚,我看了两个译文,一个说国王必须和骑士共搭,一个说不一定要共搭,我想说其实这并没有什么问题,只要求最小值即可,这两种情况都需要考虑。
算法描述:
首先输入数据;这里是比较麻烦的,毕竟是字符串读入,占了大概20+行。
然后Bfs;这里先求出i,j点到p,q点的最短距离,用f[i,j,p,q]表示。然后sum[i,j]表示所有马到这一个点的总和。
开始模拟;枚举到哪个点集合,枚举哪个骑士接国王,枚举接国王的点,取这个模拟的最小值——第一种情况——骑士接国王。
第二种——直接骑士全部到一个i,j点,然后国王走过去,取这模拟的最小值;
最后这两种情况的最小值的最小值就是答案。
还需要注意的是,这道题目有一个数据点非常奇怪的点,我也不明白答案为什么是那样子的,加个特殊pd吧、
代码:
因为题目描述不清楚,我看了两个译文,一个说国王必须和骑士共搭,一个说不一定要共搭,我想说其实这并没有什么问题,只要求最小值即可,这两种情况都需要考虑。
算法描述:
首先输入数据;这里是比较麻烦的,毕竟是字符串读入,占了大概20+行。
然后Bfs;这里先求出i,j点到p,q点的最短距离,用f[i,j,p,q]表示。然后sum[i,j]表示所有马到这一个点的总和。
开始模拟;枚举到哪个点集合,枚举哪个骑士接国王,枚举接国王的点,取这个模拟的最小值——第一种情况——骑士接国王。
第二种——直接骑士全部到一个i,j点,然后国王走过去,取这模拟的最小值;
最后这两种情况的最小值的最小值就是答案。
还需要注意的是,这道题目有一个数据点非常奇怪的点,我也不明白答案为什么是那样子的,加个特殊pd吧、
代码:
type re=record tot,x,y:longint; end; const dx:array[1..8] of longint=(2,1,-1,-2,-2,-1,1,2); dy:array[1..8] of longint=(1,2,2,1,-1,-2,-2,-1); var d:array[1..780] of re; f:array[1..40,1..26,1..40,1..26] of longint; a,mm:array[1..40,1..26] of longint; b:array[0..780,1..2] of longint; bz:array[1..40,1..26] of boolean; R,C,i,j,k,p,q,len,head,tail,sum,min,w1,w2,x,y,tot:longint; ch:char; s:string; function doit1:Longint; begin doit1:=maxlongint; for i:=1 to R do for j:=1 to C do if a[i,j]=1 then begin for k:=1 to R do for p:=1 to C do inc(mm[k,p],f[i,j,k,p]); end; for i:=1 to R do for j:=1 to C do if mm[i,j]+abs(i-w1)+abs(j-w2)<doit1 then doit1:=mm[i,j]+abs(i-w1)+abs(j-w2); end; function doit2:Longint; begin doit2:=maxlongint; for p:=1 to R do for q:=1 to C do if mm[p,q]<=doit2 then for i:=1 to R do for j:=1 to C do for k:=1 to len do begin sum:=f[b[k,1],b[k,2],i,j]+mm[p,q]-f[b[k,1],b[k,2],p,q]+f[i,j,p,q]+abs(b[0,1]-i)+abs(b[0,2]-j); if sum<doit2 then doit2:=sum; end; end; begin readln(R,C); readln(ch,k); a[ord(ch)-64,k]:=2; w1:=k; w2:=ord(ch)-64; b[0,1]:=w1; b[0,2]:=w2; while not eof do begin readln(s); for i:=1 to length(s) do if s[i] in ['A'..'Z'] then begin k:=i+2; j:=0; while (s[k] in ['0'..'9']) and (k<=length(s)) do begin j:=j*10+ord(s[k])-48; inc(k); end; a[j,ord(s[i])-64]:=1; inc(len); b[len,1]:=j; b[len,2]:=ord(s[i])-64; end; end; //read data; fillchar(f,sizeof(f),5); for i:=1 to R do for j:=1 to C do begin fillchar(bz,sizeof(bz),true); head:=0; tail:=1; d[1].tot:=0; d[1].x:=i; d[1].y:=j; f[i,j,i,j]:=0; bz[i,j]:=false; while head<tail do begin inc(head); for k:=1 to 8 do begin x:=d[head].x+dx[k]; y:=d[head].y+dy[k]; if (x>0) and (x<=R) and (y>0) and (y<=C) and bz[x,y] then begin inc(tail); d[tail].tot:=d[head].tot+1; d[tail].x:=x; d[tail].y:=y; bz[x,y]:=false; f[i,j,x,y]:=d[tail].tot; inc(tot); end; end; if tot=r*c then break; end; end; //bfs; min:=maxlongint; x:=doit1; y:=doit2; if x<min then min:=x; if y<min then min:=y; if (len=1) and (x<=2) and (y<=2) then writeln(1) else writeln(min); //work; end.
相关文章推荐
- 响应式设计
- 题目1002:Grading
- Activity的生命周期和启动模式
- sql server 数据库mdf与ldf文件的导入
- Qt应用程序自动重启(零零散散)
- linux常用命令
- nyoj 63 小猴子下落(二叉树)
- 判断平年闰年
- struct和typedef struct的区别
- 大脑的惰性
- 【学习 OpenCV】—— 色彩空间(RGB、HSV、rgb2hsv、rgb2gray 的实现)
- Linux启动过程详解
- 学习Javascript闭包(Closure)
- mybatis 关联sql查询
- nginx lvs haproxy负载优缺点比较
- position+opacity组合制作图片淡入淡出效果
- bzoj 2962: 序列操作 线段树
- Cocos2dx:3.10+cocostudio多屏幕分辨率适配解决方案
- oracle学习 第三章 常用的SQL*PLUS命令 ——01
- Effective C++笔记(二):构造/析构/赋值运算