JLOI2008 将军

题目大意:

国际象棋中一共有6种棋子:

king     (国王)

queen    (皇后)

bishop   (教主)

knight   (骑士)

rook     ()

pawn     (步兵)

queenknight不用说了;rook攻击水平和垂直两条线上的所有格子;pawn攻击前方两条斜线方向各一格;king攻击周围8个方向各1格;bishop攻击两条对角线上的所有格子。

knight以外,所有棋子的攻击范围均会被别的棋子所阻挡。(“前方”指x递增的方向,xy)

给出的棋盘上的棋子可能互相会攻击,不过你不用理会这些,你只要保证你摆放的bishop不与它们以及不互相攻击就可以了。

问在电脑给出的棋盘上,最多能放几个bishop

输入

第一行是2个整数x, y (1<=x,y<=1024)

 

下面的x行每行y个字符表示棋盘,

 

其中:

 

– king

 

– queen

 

– bishop

 

– knight

 

– rook

 

– 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里吧。

 

posted @ 2012-04-17 20:20  Codinginging  阅读(321)  评论(0编辑  收藏  举报