

调兵遣将 问题描述 我军截获的情报显示,敌军正在集结兵力试图向我军重要的军械研究所发起 进攻。由于我军正处于多线作战的状态,无法抽调大批兵力前去支援,指挥部决 定通过有效的战前部署来提高胜率,减少伤亡和损失。 该军械研究所的平面图可以看作是一个 N*M 的矩阵,每个 1*1 的格子都表 示一个区域,每个区域只与它上下左右的四个区域相邻。每个区域的用途可分为 以下 3 种之一: 1. 该区域被用于军事研究(用字母’O’表示); 2. 该区域内驻扎有一个机械化中队(用’#’表示); 3. 该区域是空地(用’.’表示)。 由于空间有限,任一个 1*1 的格子内都无法驻扎两队以上的机械化中队(包 括两队) ,否则会大大降低战斗时的机动性。 遗憾的是,由于战前估计不足,我军的防御部署显得十分分散,这很容易让 敌军所擅长的偷袭战术得逞。为了确保万无一失,我军决定利用为数不多的防御 部队以最少的移动步骤将所有重要研究区域都包围起来。 所谓的“包围”即从该矩 阵边界侵入的敌军找不到任意一条路, 使得他们不遭受任何机械化中队的反抗就 能到达某研究区域。 由于军队内部的传令权限的限制,每个单位时间指挥部只能向所有中队中的 一个中队下达指令(朝上/下/左/右移动 1 格) 。由于时间紧迫,指挥部希望能够 尽快完成部署,这个任务就交给你来完成。 注意:在部署的过程中军队可以进入研究区域,而在最终的部署结果中军队 不可以在研究区域中。另外,在任何时刻,两个军队都不可以在同一个方格中。 输入文件 该题为提交答案型试题,所有输入数据 surround1.in~surround10.in 在考试开 始前已被存入各位选手的试题目录下。 对于每个数据: 第一行包括 2 个整数 N, , M 接下来 N 行, 每行包括 M 个字符 (’.’, ’ O’或’#’)。 输出文件 针对给定的 10 个输入文件 surround1.in~surround10.in,你需要分别提交你的 输出文件 surround1.out~sourround10.out。 每个输出文件的第一行,包括你的答案所花费的时间 T 接下来 T 行,按顺序输出每条命令,每行包括 4 个整数 x1, y1, x2, y2,表示 将位于(x1,y1)的部队移向(x2,y2)。 输入样例 55 ..##. #...# #OOO# #..O# .###. 输出样例 1 2122 评分方法 如果选手的输出方案不合法(方案执行过程中出现军队重叠,军队移出矩形 边界,最终方案有军队和研究所在同一区域,军队没有包围研究所等) ,则得零 分,否则设选手输出的方案耗时为 ans ,则得分按如下计算: { 10 ans<=AI { ans-Bi {1 + trunc( ---------- ^2 *9) Ai<=ans<=Bi { Ai-Bi { 1 Bi<=ans 对于每个数据,都有两个评分参数 Ai 与 Bi ,其中保证 Ai < Bi 。 你如何测试自己的输出 我们提供 surround_check 这个工具来测试你的输出文件是否是可接受的。 使用这个工具的方法是: surround_check <输入文件名> <输出文件名> 在你调用这个程序后,surround_check 将根据你给出的输入和输出文件给出 测试的结果,其中包括: 非法退出:未知错误; overlap:出现军队重叠,或最终方案有军队和研究所在同一区域; outside:军队移出矩形边界; move error:移动一个不存在的军队,或移动距离不只一格; not surround:军队没有包围所有研究所; time not match:输出文件中移动步数与输出答案不符; yes:输出可接受,将进行下一步的评分。


1 program surround; 2 {for case 3} 3 const maxn=3010; 4 type 5 ty=record 6 x1,y1,x2,y2:longint; 7 end; 8 9 var 10 n,m,i,j,t:longint; 11 map:array[0..maxn,0..maxn] of char; 12 step:array[0..1000000] of ty; 13 get:array[0..5000,0..5000] of boolean; 14 //================== 15 procedure move(x1,y1,x2,y2:longint); 16 begin 17 if (x1=x2)and(y1=y2)or(map[x1,y1]<>'#')or(map[x2,y2]<>'.') then exit; 18 map[x1,y1]:='.'; map[x2,y2]:='#'; 19 get[x1,y1]:=true; get[x2,y2]:=true; 20 while x1<x2 do 21 begin 22 inc(t); 23 step[t].x1:=x1; step[t].y1:=y1; 24 step[t].x2:=x1+1; step[t].y2:=y1; 25 inc(x1); 26 end; 27 while x1>x2 do 28 begin 29 inc(t); 30 step[t].x1:=x1; step[t].y1:=y1; 31 step[t].x2:=x1-1; step[t].y2:=y1; 32 dec(x1); 33 end; 34 while y1<y2 do 35 begin 36 inc(t); 37 step[t].x1:=x1; step[t].y1:=y1; 38 step[t].x2:=x1; step[t].y2:=y1+1; 39 inc(y1); 40 end; 41 while y1>y2 do 42 begin 43 inc(t); 44 step[t].x1:=x1; step[t].y1:=y1; 45 step[t].x2:=x1; step[t].y2:=y1-1; 46 dec(y1); 47 end; 48 end; 49 //================== 50 procedure main(x,y:longint); 51 var 52 i:longint; 53 begin 54 get[x,y]:=true; 55 for i:=1 to 5 do move(x+i,y,x+i,y-i); 56 for i:=1 to 5 do move(x+12-i,y,x+12-i,y+i); 57 x:=x+6; 58 for i:=1 to 5 do move(x,y-6+i,x+i,y-6+i); 59 for i:=1 to 5 do move(x,y+6-i,x-i,y+6-i); 60 get[x+6,y]:=true; get[x,y-6]:=true; get[x,y+6]:=true; 61 end; 62 //=================== 63 begin 64 assign(input,'surround3.in'); reset(input); 65 assign(output,'surround3.out'); rewrite(output); 66 readln(n,m); 67 for i:=1 to n do 68 begin 69 for j:=1 to m do read(map[i,j]); 70 readln; 71 end; 72 for i:=1 to n do 73 for j:=1 to m do 74 if not get[i,j] and (map[i,j]='#') then main(i,j); 75 {for i:=1 to n do 76 begin 77 for j:=1 to m do write(map[i,j]); 78 writeln; 79 end;} 80 writeln(t); 81 for i:=1 to t do 82 writeln(step[i].x1,' ',step[i].y1,' ',step[i].x2,' ',step[i].y2); 83 close(input); close(output); 84 end.


1 program surround; 2 {for case 4} 3 const maxn=3010; 4 type 5 ty=record 6 x1,y1,x2,y2:longint; 7 end; 8 9 var 10 n,m,i,j,t:longint; 11 map:array[0..maxn,0..maxn] of char; 12 step:array[0..1000000] of ty; 13 //================== 14 procedure move(x1,y1,x2,y2:longint); 15 begin 16 if (x1=x2)and(y1=y2)or(map[x1,y1]<>'#')or(map[x2,y2]<>'.') then exit; 17 map[x1,y1]:='.'; map[x2,y2]:='#'; 18 while x1<x2 do 19 begin 20 inc(t); 21 step[t].x1:=x1; step[t].y1:=y1; 22 step[t].x2:=x1+1; step[t].y2:=y1; 23 inc(x1); 24 end; 25 while x1>x2 do 26 begin 27 inc(t); 28 step[t].x1:=x1; step[t].y1:=y1; 29 step[t].x2:=x1-1; step[t].y2:=y1; 30 dec(x1); 31 end; 32 while y1<y2 do 33 begin 34 inc(t); 35 step[t].x1:=x1; step[t].y1:=y1; 36 step[t].x2:=x1; step[t].y2:=y1+1; 37 inc(y1); 38 end; 39 while y1>y2 do 40 begin 41 inc(t); 42 step[t].x1:=x1; step[t].y1:=y1; 43 step[t].x2:=x1; step[t].y2:=y1-1; 44 dec(y1); 45 end; 46 end; 47 //================== 48 begin 49 assign(input,'surround4.in'); reset(input); 50 assign(output,'surround4.out'); rewrite(output); 51 readln(n,m); 52 for i:=1 to n do 53 begin 54 for j:=1 to m do read(map[i,j]); 55 readln; 56 end; 57 for j:=1 to 6 do 58 for i:=6 downto 1 do 59 begin 60 if i<>4 then 61 begin 62 if i<=3 then 63 begin 64 move(2,j*13+5-(i-1) shl 1,i*13,j*13-1); 65 move(1,j*13+5-(i-1) shl 1,i*13-1,j*13); 66 move(2,j*13+6-(i-1) shl 1,i*13+1,j*13); 67 move(1,j*13+6-(i-1) shl 1,i*13,j*13+1); 68 end else 69 begin 70 move(2,j*13+5-(i-1) shl 1,i*13+1,j*13); 71 move(2,j*13+6-(i-1) shl 1,i*13,j*13+1); 72 move(1,j*13+5-(i-1) shl 1,i*13,j*13-1); 73 move(1,j*13+6-(i-1) shl 1,i*13-1,j*13); 74 end; 75 end else 76 begin 77 move(2,j*13+5-(i-1) shl 1,i*13,j*13+1); 78 move(1,j*13+5-(i-1) shl 1,i*13,j*13-1); 79 move(2,j*13+6-(i-1) shl 1,i*13+1,j*13); 80 move(1,j*13+6-(i-1) shl 1,i*13-1,j*13); 81 end; 82 end; 83 {for i:=1 to n do 84 begin 85 for j:=1 to m do write(map[i,j]); 86 writeln; 87 end;} 88 writeln(t); 89 for i:=1 to t do 90 writeln(step[i].x1,' ',step[i].y1,' ',step[i].x2,' ',step[i].y2); 91 close(input); close(output); 92 end.


1 program surround; 2 {for case 5} 3 const maxn=3010; 4 type 5 ty=record 6 x1,y1,x2,y2:longint; 7 end; 8 9 var 10 n,m,i,j,t:longint; 11 can:boolean; 12 map:array[0..maxn,0..maxn] of char; 13 get:array[0..maxn,0..maxn] of boolean; 14 step:array[0..10000000] of ty; 15 //================== 16 procedure move(x1,y1,x2,y2:longint); 17 begin 18 map[x1,y1]:='.'; map[x2,y2]:='#'; 19 get[x1,y1]:=true; get[x2,y2]:=true; 20 while x1<x2 do 21 begin 22 inc(t); 23 step[t].x1:=x1; step[t].y1:=y1; 24 step[t].x2:=x1+1; step[t].y2:=y1; 25 inc(x1); 26 end; 27 while x1>x2 do 28 begin 29 inc(t); 30 step[t].x1:=x1; step[t].y1:=y1; 31 step[t].x2:=x1-1; step[t].y2:=y1; 32 dec(x1); 33 end; 34 while y1<y2 do 35 begin 36 inc(t); 37 step[t].x1:=x1; step[t].y1:=y1; 38 step[t].x2:=x1; step[t].y2:=y1+1; 39 inc(y1); 40 end; 41 while y1>y2 do 42 begin 43 inc(t); 44 step[t].x1:=x1; step[t].y1:=y1; 45 step[t].x2:=x1; step[t].y2:=y1-1; 46 dec(y1); 47 end; 48 end; 49 //================== 50 procedure run1(x,y:longint); 51 var 52 i,j,len:longint; 53 begin 54 len:=0; j:=x; 55 while map[j+1,y]='.' do begin inc(len); inc(j); end; 56 for i:=1 to len do move(x,y+i-1,x+len-i+1,y+i-1); 57 for i:=1 to len do move(x+len+i+1,y-1,x+len+i+1,y-1+i); 58 for i:=1 to len do move(x+i,y+(len<<1)+1,x+i,y+(len<<1)+1-(len-i+1)); 59 for i:=1 to len do move(x+(len<<1)+2,y+len+i,x+(len<<1)+2-i,y+len+i); 60 y:=y+len; 61 for i:=0 to len+1 do 62 for j:=y-i to y+i do 63 get[x+i,j]:=true; 64 x:=x+len shl 1+2; 65 for i:=0 to len do 66 for j:=y-i to y+i do 67 get[x-i,j]:=true; 68 end; 69 //================== 70 procedure run2(x,y:longint); 71 var 72 i,j,len:longint; 73 begin 74 len:=0; j:=x; 75 while map[j+1,y+1]='.' do begin inc(len); inc(j); end; 76 for i:=1 to len do move(x,y+i,x+i,y+i); 77 for i:=1 to len do move(x+(len<<1)+2,y-i,x+(len<<1)+2-i,y-i); 78 for i:=1 to len do move(x+i,y-len-1,x+i,y-i); 79 for i:=1 to len do move(x+len+1+i,y+len+1,x+len+1+i,y+len+1-i); 80 for i:=0 to len+1 do 81 for j:=y-i to y+i do get[x+i,j]:=true; 82 x:=x+len shl 1+2; 83 for i:=0 to len do 84 for j:=y-i to y+i do get[x-i,j]:=true; 85 end; 86 //================== 87 begin 88 assign(input,'surround5.in'); reset(input); 89 assign(output,'surround5.out'); rewrite(output); 90 readln(n,m); 91 for i:=1 to n do 92 begin 93 for j:=1 to m do read(map[i,j]); 94 readln; 95 end; 96 for i:=1 to n do 97 for j:=1 to m do 98 if not get[i,j] and (map[i,j]='#') then 99 begin 100 if map[i+1,j]='.' then run1(i,j) 101 else run2(i,j); 102 end; 103 {for i:=1 to n do 104 begin 105 for j:=1 to m do write(map[i,j]); 106 writeln; 107 end;} 108 writeln(t); 109 for i:=1 to t do 110 writeln(step[i].x1,' ',step[i].y1,' ',step[i].x2,' ',step[i].y2); 111 close(input); close(output); 112 end.


1 program surround; 2 {for case 8} 3 const maxn=3010; 4 type 5 ty=record 6 x1,y1,x2,y2:longint; 7 end; 8 9 var 10 n,m,i,j,t:longint; 11 map:array[0..maxn,0..maxn] of char; 12 get:array[0..maxn,0..maxn] of boolean; 13 step:array[0..10000000] of ty; 14 //================== 15 procedure move(x1,y1,x2,y2:longint); 16 begin 17 if (x1=x2)and(y1=y2)or(map[x1,y1]<>'#')or(map[x2,y2]<>'.') then exit; 18 map[x1,y1]:='.'; map[x2,y2]:='#'; 19 while x1<x2 do 20 begin 21 inc(t); 22 step[t].x1:=x1; step[t].y1:=y1; 23 step[t].x2:=x1+1; step[t].y2:=y1; 24 inc(x1); 25 end; 26 while x1>x2 do 27 begin 28 inc(t); 29 step[t].x1:=x1; step[t].y1:=y1; 30 step[t].x2:=x1-1; step[t].y2:=y1; 31 dec(x1); 32 end; 33 while y1<y2 do 34 begin 35 inc(t); 36 step[t].x1:=x1; step[t].y1:=y1; 37 step[t].x2:=x1; step[t].y2:=y1+1; 38 inc(y1); 39 end; 40 while y1>y2 do 41 begin 42 inc(t); 43 step[t].x1:=x1; step[t].y1:=y1; 44 step[t].x2:=x1; step[t].y2:=y1-1; 45 dec(y1); 46 end; 47 end; 48 //================== 49 procedure main(x,y:longint); 50 var 51 i,j,len:longint; 52 begin 53 len:=0; i:=x; j:=y; 54 while map[i,j]='O' do begin inc(len); inc(j); end; 55 for i:=1 to (len+1) shr 1 do 56 begin 57 move(x-(len-i+1),y+i-1,x-i,y+i-1); 58 move(x+i-1,y-(len-i+1),x+i-1,y-i); 59 move(x+len-1+(len-i+1),y+i-1,x+len-1+i,y+i-1); 60 move(x+i-1,y+len-1+(len-i+1),x+i-1,y+len-1+i); 61 end; 62 for i:=1 to (len+1) shr 1 do 63 begin 64 move(x-(len-i+1),y+len-i,x-i,y+len-i); 65 move(x+len-i,y-(len-i+1),x+len-i,y-i); 66 move(x+len-1+(len-i+1),y+len-i,x+len-1+i,y+len-i); 67 move(x+len-i,y+len-1+(len-i+1),x+len-i,y+len-1+i); 68 end; 69 for i:=x to x+len-1 do 70 for j:=y to y+len-1 do get[i,j]:=true; 71 end; 72 //================== 73 begin 74 assign(input,'surround8.in'); reset(input); 75 assign(output,'surround8.out'); rewrite(output); 76 readln(n,m); 77 for i:=1 to n do 78 begin 79 for j:=1 to m do read(map[i,j]); 80 readln; 81 end; 82 for i:=1 to n do 83 for j:=1 to m do 84 if not get[i,j] and (map[i,j]='O') then main(i,j); 85 {for i:=1 to n do 86 begin 87 for j:=1 to m do write(map[i,j]); 88 writeln; 89 end;} 90 writeln(t); 91 for i:=1 to t do 92 writeln(step[i].x1,' ',step[i].y1,' ',step[i].x2,' ',step[i].y2); 93 close(input); close(output); 94 end.


1 program surround; 2 {for case 6/7/9/10} 3 const maxn=3010; 4 type 5 ty=record 6 x1,y1,x2,y2:longint; 7 end; 8 9 var 10 n,m,i,j,t,k:longint; 11 map:array[0..maxn,0..maxn] of char; 12 get:array[0..maxn,0..maxn] of boolean; 13 step:array[0..10000000] of ty; 14 //================== 15 procedure move(x1,y1,x2,y2:longint); 16 begin 17 if (x1=x2)and(y1=y2)or(map[x1,y1]<>'#')or(map[x2,y2]<>'.') then exit; 18 map[x1,y1]:='.'; map[x2,y2]:='#'; 19 while x1<x2 do 20 begin 21 inc(t); 22 step[t].x1:=x1; step[t].y1:=y1; 23 step[t].x2:=x1+1; step[t].y2:=y1; 24 inc(x1); 25 end; 26 while x1>x2 do 27 begin 28 inc(t); 29 step[t].x1:=x1; step[t].y1:=y1; 30 step[t].x2:=x1-1; step[t].y2:=y1; 31 dec(x1); 32 end; 33 while y1<y2 do 34 begin 35 inc(t); 36 step[t].x1:=x1; step[t].y1:=y1; 37 step[t].x2:=x1; step[t].y2:=y1+1; 38 inc(y1); 39 end; 40 while y1>y2 do 41 begin 42 inc(t); 43 step[t].x1:=x1; step[t].y1:=y1; 44 step[t].x2:=x1; step[t].y2:=y1-1; 45 dec(y1); 46 end; 47 end; 48 //================== 49 begin 50 assign(input,'surround9.in'); reset(input); 51 assign(output,'surround9.out'); rewrite(output); 52 readln(n,m); 53 for i:=1 to n do 54 begin 55 for j:=1 to m do read(map[i,j]); 56 readln; 57 end; 58 for i:=1 to n do 59 for j:=1 to m do 60 if map[i,j]='.' then 61 begin 62 if (i=1)and(j<>1)and(j<>m) then 63 begin 64 k:=i; 65 while (k<=n)and(map[k,j]<>'#') do inc(k); 66 move(k,j,i,j); 67 end else 68 if (i=n)and(j<>1)and(j<>m) then 69 begin 70 k:=i; 71 while (k>0)and(map[k,j]<>'#') do dec(k); 72 move(k,j,i,j); 73 end else 74 if (j=1)and(i<>1)and(i<>n) then 75 begin 76 k:=j; 77 while (k<=m)and(map[i,k]<>'#') do inc(k); 78 move(i,k,i,j); 79 end else 80 if (j=m)and(i<>1)and(i<>n) then 81 begin 82 k:=j; 83 while (k>0)and(map[i,k]<>'#') do dec(k); 84 move(i,k,i,j); 85 end; 86 end; 87 {for i:=1 to n do 88 begin 89 for j:=1 to m do write(map[i,j]); 90 writeln; 91 end;} 92 writeln(t); 93 for i:=1 to t do 94 writeln(step[i].x1,' ',step[i].y1,' ',step[i].x2,' ',step[i].y2); 95 close(input); close(output); 96 end.