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

     

  • 相关阅读:
    js 复制到剪切板
    200-api网关工程过滤器设置
    199-Zuul配置文件
    198-Feign有什么方便之处呢?
    12-sublime中文配置
    098-Servlet为什么直接相应给浏览器的信息会出现乱码?
    097-为什么我们在SpirngBoot中设置了响应头的编码,浏览器解析出来依然回事乱码呢?
    196-为什么SpringBoot框架中不能直接使用@WebServlet的注解?
    195-如何获取Spring容器中的对象?
    194-Spring注入属性的几个注解?
  • 原文地址:https://www.cnblogs.com/neverforget/p/2454227.html
Copyright © 2011-2022 走看看