zoukankan      html  css  js  c++  java
  • 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里吧。

     

  • 相关阅读:
    PAT 1097. Deduplication on a Linked List (链表)
    PAT 1096. Consecutive Factors
    PAT 1095. Cars on Campus
    PAT 1094. The Largest Generation (层级遍历)
    PAT 1093. Count PAT's
    PAT 1092. To Buy or Not to Buy
    PAT 1091. Acute Stroke (bfs)
    CSS:word-wrap/overflow/transition
    node-webkit中的requirejs报错问题:path must be a string error in Require.js
    script加载之defer和async
  • 原文地址:https://www.cnblogs.com/neverforget/p/2454227.html
Copyright © 2011-2022 走看看