【搜索】【NOIP2011提高组Day1】Mayan游戏

 

【样例输入输出1】

mayan.inmayan.out
3
1 0
2 1 0
2 3 4 0
3 1 0
2 4 3 4 0
2 1 1
3 1 1
3 0 1

 

这是一道很难的搜索题,标称见http://www.rqnoj.cn/Discuss_Show.asp?DID=10656(C++)

              http://www.rqnoj.cn/Discuss_Show.asp?DID=11103(Pascal)

不过就算做不到,也可以打表,由于有30%的数据是只有一行,所以完全可以把所有情况都打出来,然后剩下的就cheat -1。这种方法能得40分!

 

打表Pascal Code(有点长)

program mayan;
//本来想宽搜的,结果没写出来,所以下面这些宽搜的变量可以无视。。。
type
  armap=array[0..7,0..5] of longint;
  tnode=record
    node:armap;
    step:longint;
    x,y:longint;//要移动的节点坐标
    number:longint;//父节点  用于输出
  end;

var
  steps:longint;//步数  即题目中的n
  map:armap;
  l,r:longint;
  q:array[0..7*5*5*7*5*7+10] of tnode;
  first,target:tnode;

procedure init;
begin
  assign(input,'mayan.in');
  assign(output,'mayan.out');
  reset(input);
  rewrite(output);
end;

procedure outit;
begin
  close(input);
  close(output);
  halt;
end;

procedure readdata;
var
  i,num,x:longint;
begin
  read(steps);
  num:=0;
  for i:=1 to 5 do
  begin
    read(x);
    while x<>0 do
    begin
      inc(num);
      map[num,i]:=x;
      read(x);
    end;
    num:=0;
  end;
 { for i:=1 to 7 do
  begin
    for x:=1 to 5 do
      if map[i,x]=0 then write('  ')
      else write(map[i,x],' ');
    writeln;
  end;}
end;

procedure percent30;
var
  i:longint;
  flag:longint;
  num:longint;
  k:array[1..3] of longint;//记录flag=3时的颜色状态
begin
  flag:=0;
  for i:=1 to 5 do
    if map[1,i]<>0 then
      inc(flag);//flag为1,2,4和5时必定无法消完
  if flag in [1,2,4,5] then
  begin
    writeln(-1);
    outit;
  end;
  //处理剩下flag=3的情况
  num:=0;
  for i:=1 to 5 do
    if map[1,i]<>0 then
    begin
      inc(num);
      k[num]:=map[1,i];
    end;
  if not((k[1]=k[2])or(k[2]=k[3])or(k[1]=k[3])) then
  begin
    writeln(-1);
    outit;
  end;
  //剩下只有第一行有三个并且颜色相同 且要在刚好steps步数下完成
  //(由于初始状态无可消除的 所以只有三种情况 打表。。。)
  for i:=1 to 5 do if map[1,i]<>0 then map[1,i]:=1 else map[1,i]:=0;//把有颜色的处理成1
  //三种情况分别为1 1 0 1 0      1 1 0 0 1     1 0 1 0 1
  if (map[1,1]=1)and(map[1,2]=1)and(map[1,3]=0)and(map[1,4]=1)and(map[1,5]=0) then
  begin//1 1 0 1 0
    if steps=1 then
    begin
      writeln('3 0 -1');
      outit;
    end
    else if steps=2 then
    begin
      writeln('1 0 1');
      writeln('0 0 1');
      outit;
    end
    else if steps=4 then
    begin
      writeln('3 0 1');
      writeln('1 0 1');
      writeln('0 0 1');
      writeln('1 0 1');
      outit;
    end
    else begin
      writeln(-1);
      outit;
    end;
  end
  else if (map[1,1]=1)and(map[1,2]=1)and(map[1,3]=0)and(map[1,4]=0)and(map[1,5]=1) then
  begin//1 1 0 0 1
    if steps=2 then
    begin
      writeln('4 0 -1');
      writeln('3 0 -1');
      outit;
    end
    else if steps=3 then
    begin
      writeln('1 0 1');
      writeln('0 0 1');
      writeln('4 0 -1');
      outit;
    end
    else if steps=4 then
    begin
      writeln('1 0 1');
      writeln('0 0 1');
      writeln('2 0 1');
      writeln('1 0 1');
      outit;
    end
    else begin
      writeln(-1);
      outit;
    end;
  end
  else if (map[1,1]=1)and(map[1,2]=0)and(map[1,3]=1)and(map[1,4]=0)and(map[1,5]=1) then
  begin//1 0 1 0 1
    if steps=2 then
    begin
      writeln('0 0 1');
      writeln('4 0 -1');
      outit;
    end
    else if steps=3 then
    begin
      writeln('0 0 1');
      writeln('2 0 1');
      writeln('1 0 1');
      outit;
    end
    else begin
      writeln(-1);
      outit;
    end;
  end
  else begin
    writeln(-1);
    outit;
  end;
end;

procedure main;
var
  i:longint;
  flag:boolean;
begin
  flag:=true;
  for i:=1 to 5 do
    if map[2,i]<>0 then
      flag:=false;//flag=true时表示第二行没有方块 即只有第一行有方块
      
  if flag then percent30;//处理30%的数据  都在最下面一行 即map[1,1~5]
  if not flag then writeln(-1);//剩下的直接cheat -1
end;


begin
  init;
  readdata;
  main;
  outit;
end.

 

 

转载于:https://www.cnblogs.com/oijzh/archive/2012/08/20/2647039.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值