JLOI2008 将军
题目大意:
国际象棋中一共有6种棋子:
king (国王)
queen (皇后)
bishop (教主)
knight (骑士)
rook (车)
pawn (步兵)
queen和knight不用说了;rook攻击水平和垂直两条线上的所有格子;pawn攻击前方两条斜线方向各一格;king攻击周围8个方向各1格;bishop攻击两条对角线上的所有格子。
除knight以外,所有棋子的攻击范围均会被别的棋子所阻挡。(“前方”指x递增的方向,x行y列)。
给出的棋盘上的棋子可能互相会攻击,不过你不用理会这些,你只要保证你摆放的bishop不与它们以及不互相攻击就可以了。
问在电脑给出的棋盘上,最多能放几个bishop。
输入:
第一行是2个整数x, y (1<=x,y<=1024),
下面的x行每行y个字符表示棋盘,
其中:
K – king
Q – queen
B – bishop
N – knight
R – rook
P – pawn
“.” – blank.
把所有不能放棋子的地方都标记出来,在剩余的空格中,一个bishop会控制两个对角线,我们将这两条对角线看做二分图中的点,在它们之间连边,那么每一条边代表一个bishop,最多的bishop数就对应着这个二分图中的最大匹配。
处理时用前向星存,最后一个点棋盘很空,用矩阵或临接表都会超时。边数巨多无比,前向星数组少于90W就越界了。。。
链表邻接表(极限数据4.0s++)
View Code
1 program checkmate(input,output); 2 type 3 node = ^link; 4 link = record 5 goal : longint; 6 next : node; 7 end; 8 var 9 map : array[0..1500,0..1500] of integer; 10 l : array[0..5000] of node; 11 lk : array[0..5000] of longint; 12 v : array[0..5000] of boolean; 13 answer : longint; 14 n,m : integer; 15 move : integer; 16 procedure init; 17 var 18 i,j : longint; 19 ch : char; 20 begin 21 readln(n,m); 22 move:=m+n+m; 23 fillchar(map,sizeof(map),0); 24 for i:=1 to n do 25 begin 26 for j:=1 to m do 27 begin 28 read(ch); 29 case ch of 30 'K' : map[i,j]:=2; 31 'Q' : map[i,j]:=3; 32 'B' : map[i,j]:=4; 33 'N' : map[i,j]:=5; 34 'R' : map[i,j]:=6; 35 'P' : map[i,j]:=7; 36 end; { case } 37 end; 38 readln; 39 end; 40 end;{ init } 41 procedure up(x,y : longint); 42 begin 43 dec(x); 44 while (x>0) do 45 begin 46 if map[x,y]>=2 then 47 exit; 48 map[x,y]:=-1; 49 dec(x); 50 end; 51 end; { up } 52 procedure down(x,y :longint ); 53 begin 54 inc(x); 55 while (x<=n) do 56 begin 57 if map[x,y]>=2 then 58 exit; 59 map[x,y]:=-1; 60 inc(x); 61 end; 62 end; { down } 63 procedure left(x,y :longint ); 64 begin 65 dec(y); 66 while y>0 do 67 begin 68 if map[x,y]>=2 then 69 exit; 70 map[x,y]:=-1; 71 dec(y); 72 end; 73 end; { left } 74 procedure right(x,y :longint ); 75 begin 76 inc(y); 77 while y<=m do 78 begin 79 if map[x,y]>=2 then 80 exit; 81 map[x,y]:=-1; 82 inc(y); 83 end; 84 end; { right } 85 procedure change(x,y :longint ); 86 begin 87 if (x<=0)or(x>n) then 88 exit; 89 if (y<=0)or(y>m) then 90 exit; 91 if map[x,y]>=2 then 92 exit; 93 map[x,y]:=-1; 94 end; { change } 95 procedure left_up(x,y :longint ); 96 begin 97 dec(x); 98 dec(y); 99 while (x>0)and(y>0) do 100 begin 101 if map[x,y]>=2 then 102 exit; 103 map[x,y]:=-1; 104 dec(x); 105 dec(y); 106 end; 107 end; { left_up } 108 procedure right_up(x,y :longint ); 109 begin 110 dec(x); 111 inc(y); 112 while (x>0)and(y<=m) do 113 begin 114 if map[x,y]>=2 then 115 exit; 116 map[x,y]:=-1; 117 dec(x); 118 inc(y); 119 end; 120 end; { right_up } 121 procedure left_down(x,y :longint ); 122 begin 123 inc(x); 124 dec(y); 125 while (x<=n)and(y>0) do 126 begin 127 if map[x,y]>=2 then 128 exit; 129 map[x,y]:=-1; 130 inc(x); 131 dec(y); 132 end; 133 end; { left_down } 134 procedure right_down(x,y :longint ); 135 begin 136 inc(x); 137 inc(y); 138 while (x<=n)and(y<=m) do 139 begin 140 if map[x,y]>=2 then 141 exit; 142 map[x,y]:=-1; 143 inc(x); 144 inc(y); 145 end; 146 end; { right_down } 147 procedure previous(); 148 var 149 i,j : longint; 150 begin 151 for i:=1 to n do 152 for j:=1 to m do 153 case map[i,j] of 154 2 : begin 155 change(i-1,j-1); 156 change(i-1,j); 157 change(i-1,j+1); 158 change(i,j-1); 159 change(i,j+1); 160 change(i+1,j+1); 161 change(i+1,j); 162 change(i+1,j-1); 163 left_up(i,j); 164 right_up(i,j); 165 left_down(i,j); 166 right_down(i,j); 167 end; 168 3 : begin 169 up(i,j); 170 down(i,j); 171 left(i,j); 172 right(i,j); 173 left_up(i,j); 174 right_up(i,j); 175 left_down(i,j); 176 right_down(i,j); 177 end; 178 4 : begin 179 left_up(i,j); 180 right_up(i,j); 181 left_down(i,j); 182 right_down(i,j); 183 end; 184 5 : begin 185 change(i-2,j-1); 186 change(i-2,j+1); 187 change(i-1,j-2); 188 change(i-1,j+2); 189 change(i+1,j+2); 190 change(i+1,j-2); 191 change(i+2,j-1); 192 change(i+2,j+1); 193 left_up(i,j); 194 right_up(i,j); 195 left_down(i,j); 196 right_down(i,j); 197 end; 198 6 : begin 199 up(i,j); 200 down(i,j); 201 left(i,j); 202 right(i,j); 203 left_up(i,j); 204 right_up(i,j); 205 left_down(i,j); 206 right_down(i,j); 207 end; 208 7 : begin 209 change(i+1,j+1); 210 change(i+1,j-1); 211 left_up(i,j); 212 right_up(i,j); 213 left_down(i,j); 214 right_down(i,j); 215 end; 216 end; { case } 217 end;{ previous } 218 procedure add(xx,yy :longint ); 219 var 220 tt : node; 221 begin 222 new(tt); 223 tt^.goal:=yy; 224 tt^.next:=l[xx]; 225 l[xx]:=tt; 226 end; { add } 227 procedure make_graph(); 228 var 229 i,j : longint; 230 begin 231 for i:=1 to n do 232 for j:=1 to m do 233 if map[i,j]=0 then 234 add(i+j,i-j+move); 235 end; { make_graph } 236 function find(now :longint ):boolean; 237 var 238 t : node; 239 begin 240 t:=l[now]; 241 while t<>nil do 242 begin 243 if not v[t^.goal] then 244 begin 245 v[t^.goal]:=true; 246 if (lk[t^.goal]=0)or(find(lk[t^.goal])) then 247 begin 248 lk[t^.goal]:=now; 249 exit(true); 250 end; 251 end; 252 t:=t^.next; 253 end; 254 exit(false); 255 end; { find } 256 procedure main; 257 var 258 i : longint; 259 begin 260 answer:=0; 261 fillchar(lk,sizeof(lk),0); 262 for i:=2 to n+m do 263 begin 264 fillchar(v,sizeof(v),false); 265 if find(i) then 266 inc(answer); 267 end; 268 end; { main } 269 procedure print; 270 begin 271 writeln(answer); 272 end; { print } 273 begin 274 assign(input,'checkmate.in');reset(input); 275 assign(output,'checkmate.out');rewrite(output); 276 init(); 277 previous(); 278 make_graph(); 279 main(); 280 print(); 281 close(input); 282 close(output); 283 end.
前向星(极限数据0.23s)
View Code
1 program checkmate(input,output); 2 var 3 tot : longint; 4 x,y,f : array[0..1000000] of longint; 5 map : array[0..1500,0..1500] of integer; 6 lk : array[0..5000] of longint; 7 v : array[0..5000] of boolean; 8 answer : longint; 9 n,m : integer; 10 move : integer; 11 procedure init; 12 var 13 i,j : longint; 14 ch : char; 15 begin 16 readln(n,m); 17 tot:=0; 18 move:=m+n+m; 19 fillchar(map,sizeof(map),0); 20 for i:=1 to n do 21 begin 22 for j:=1 to m do 23 begin 24 read(ch); 25 case ch of 26 'K' : map[i,j]:=2; 27 'Q' : map[i,j]:=3; 28 'B' : map[i,j]:=4; 29 'N' : map[i,j]:=5; 30 'R' : map[i,j]:=6; 31 'P' : map[i,j]:=7; 32 end; { case } 33 end; 34 readln; 35 end; 36 end;{ init } 37 procedure up(x,y : longint); 38 begin 39 dec(x); 40 while (x>0) do 41 begin 42 if map[x,y]>=2 then 43 exit; 44 map[x,y]:=-1; 45 dec(x); 46 end; 47 end; { up } 48 procedure down(x,y :longint ); 49 begin 50 inc(x); 51 while (x<=n) do 52 begin 53 if map[x,y]>=2 then 54 exit; 55 map[x,y]:=-1; 56 inc(x); 57 end; 58 end; { down } 59 procedure left(x,y :longint ); 60 begin 61 dec(y); 62 while y>0 do 63 begin 64 if map[x,y]>=2 then 65 exit; 66 map[x,y]:=-1; 67 dec(y); 68 end; 69 end; { left } 70 procedure right(x,y :longint ); 71 begin 72 inc(y); 73 while y<=m do 74 begin 75 if map[x,y]>=2 then 76 exit; 77 map[x,y]:=-1; 78 inc(y); 79 end; 80 end; { right } 81 procedure change(x,y :longint ); 82 begin 83 if (x<=0)or(x>n) then 84 exit; 85 if (y<=0)or(y>m) then 86 exit; 87 if map[x,y]>=2 then 88 exit; 89 map[x,y]:=-1; 90 end; { change } 91 procedure left_up(x,y :longint ); 92 begin 93 dec(x); 94 dec(y); 95 while (x>0)and(y>0) do 96 begin 97 if map[x,y]>=2 then 98 exit; 99 map[x,y]:=-1; 100 dec(x); 101 dec(y); 102 end; 103 end; { left_up } 104 procedure right_up(x,y :longint ); 105 begin 106 dec(x); 107 inc(y); 108 while (x>0)and(y<=m) do 109 begin 110 if map[x,y]>=2 then 111 exit; 112 map[x,y]:=-1; 113 dec(x); 114 inc(y); 115 end; 116 end; { right_up } 117 procedure left_down(x,y :longint ); 118 begin 119 inc(x); 120 dec(y); 121 while (x<=n)and(y>0) do 122 begin 123 if map[x,y]>=2 then 124 exit; 125 map[x,y]:=-1; 126 inc(x); 127 dec(y); 128 end; 129 end; { left_down } 130 procedure right_down(x,y :longint ); 131 begin 132 inc(x); 133 inc(y); 134 while (x<=n)and(y<=m) do 135 begin 136 if map[x,y]>=2 then 137 exit; 138 map[x,y]:=-1; 139 inc(x); 140 inc(y); 141 end; 142 end; { right_down } 143 procedure previous(); 144 var 145 i,j : longint; 146 begin 147 for i:=1 to n do 148 for j:=1 to m do 149 case map[i,j] of 150 2 : begin 151 change(i-1,j-1); 152 change(i-1,j); 153 change(i-1,j+1); 154 change(i,j-1); 155 change(i,j+1); 156 change(i+1,j+1); 157 change(i+1,j); 158 change(i+1,j-1); 159 left_up(i,j); 160 right_up(i,j); 161 left_down(i,j); 162 right_down(i,j); 163 end; 164 3 : begin 165 up(i,j); 166 down(i,j); 167 left(i,j); 168 right(i,j); 169 left_up(i,j); 170 right_up(i,j); 171 left_down(i,j); 172 right_down(i,j); 173 end; 174 4 : begin 175 left_up(i,j); 176 right_up(i,j); 177 left_down(i,j); 178 right_down(i,j); 179 end; 180 5 : begin 181 change(i-2,j-1); 182 change(i-2,j+1); 183 change(i-1,j-2); 184 change(i-1,j+2); 185 change(i+1,j+2); 186 change(i+1,j-2); 187 change(i+2,j-1); 188 change(i+2,j+1); 189 left_up(i,j); 190 right_up(i,j); 191 left_down(i,j); 192 right_down(i,j); 193 end; 194 6 : begin 195 up(i,j); 196 down(i,j); 197 left(i,j); 198 right(i,j); 199 left_up(i,j); 200 right_up(i,j); 201 left_down(i,j); 202 right_down(i,j); 203 end; 204 7 : begin 205 change(i+1,j+1); 206 change(i+1,j-1); 207 left_up(i,j); 208 right_up(i,j); 209 left_down(i,j); 210 right_down(i,j); 211 end; 212 end; { case } 213 end;{ previous } 214 procedure add(xx,yy :longint ); 215 begin 216 inc(tot); 217 x[tot]:=xx; 218 y[tot]:=yy; 219 end; { add } 220 procedure make_graph(); 221 var 222 i,j : longint; 223 begin 224 for i:=1 to n do 225 for j:=1 to m do 226 if map[i,j]=0 then 227 add(i+j,i-j+move); 228 end; { make_graph } 229 procedure swap(var aa,bb :longint ); 230 var 231 tt : longint; 232 begin 233 tt:=aa; 234 aa:=bb; 235 bb:=tt; 236 end; { swap } 237 procedure sort(p,q :longint ); 238 var 239 mid : longint; 240 i,j : longint; 241 begin 242 i:=p; 243 j:=q; 244 mid:=x[(i+j)>>1]; 245 repeat 246 while x[i]<mid do 247 inc(i); 248 while x[j]>mid do 249 dec(j); 250 if i<=j then 251 begin 252 swap(x[i],x[j]); 253 swap(y[i],y[j]); 254 inc(i); 255 dec(j); 256 end; 257 until i>j; 258 if i<q then sort(i,q); 259 if j>p then sort(p,j); 260 end; { sort } 261 procedure make(); 262 var 263 i : longint; 264 begin 265 fillchar(f,sizeof(f),0); 266 for i:=1 to tot do 267 if f[x[i]]=0 then 268 f[x[i]]:=i; 269 f[n-1+move+1]:=tot+1; 270 for i:=n+move downto 1 do 271 if f[i]=0 then 272 f[i]:=f[i+1]; 273 end; { make } 274 function find(now: longint ):boolean; 275 var 276 i : longint; 277 begin 278 for i:=f[now] to f[now+1]-1 do 279 begin 280 if not v[y[i]] then 281 begin 282 v[y[i]]:=true; 283 if (lk[y[i]]=0)or(find(lk[y[i]])) then 284 begin 285 lk[y[i]]:=now; 286 exit(true); 287 end; 288 end; 289 end; 290 exit(false); 291 end; { find } 292 procedure main; 293 var 294 i : longint; 295 begin 296 answer:=0; 297 fillchar(lk,sizeof(lk),0); 298 for i:=2 to n+m do 299 begin 300 fillchar(v,sizeof(v),false); 301 if find(i) then 302 inc(answer); 303 end; 304 end; { main } 305 procedure print; 306 begin 307 writeln(answer); 308 end; { print } 309 begin 310 assign(input,'checkmate.in');reset(input); 311 assign(output,'checkmate.out');rewrite(output); 312 init(); 313 previous(); 314 make_graph(); 315 sort(1,tot); 316 make(); 317 main(); 318 print(); 319 close(input); 320 close(output); 321 end.
都是省选题,暂且归到八中oj里吧。