2016年提高组模拟试题(20161105)Mahjong

Description
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

题解

两个字:暴力!然后要耐心、细心、专心、慢慢、渐渐的调试,缓缓的卡成AC。
他妈的,好崩溃啊!和某年NOIP的斗地主一样啃爹啊!

代码

type
  arr=record
        num,op,s,id:longint;
      end;
  arrr=array [0..20] of arr;
var
  use:array [0..5,0..20] of longint;
  n,m,num,sum:longint;
  a,b,c:arrr;

function min(o,p:longint):longint;
begin
  if o<p then exit(o);
  exit(p);
end;

procedure qsort(l,r:longint; var ab:arrr);
var
  i,j:longint;
  mid,t:arr;
begin
  if l>r then exit;
  i:=l; j:=r;
  mid:=ab[(l+r) div 2];
  repeat
    while (ab[i].op<mid.op) or (ab[i].op=mid.op) and (ab[i].num<mid.num) do inc(i);
    while (ab[j].op>mid.op) or (ab[j].op=mid.op) and (ab[j].num>mid.num) do dec(j);
    if i<=j then
      begin
        t:=ab[i]; ab[i]:=ab[j]; ab[j]:=t;
        inc(i); dec(j);
      end;
  until i>j;
  qsort(i,r,ab);
  qsort(l,j,ab);
end;

procedure init;
var
  i:longint;
  c1,c2,c3:char;
begin
  for i:=1 to 14 do
    begin
      read(c1,c2,c3);
      if c2='s' then a[i].op:=1
        else if c2='w' then a[i].op:=2
          else a[i].op:=3;
        a[i].num:=ord(c1)-48;
        a[i].s:=1; a[i].id:=i;
      end;
end;

procedure try1;
var
  i:longint;
begin
  n:=14;
  for i:=1 to 13 do
    if (a[i].op=a[i+1].op) and (a[i].num=a[i+1].num) then
      begin
        a[i].op:=4;
        dec(n);
        inc(a[i+1].s,a[i].s);
        a[i+1].id:=min(a[i+1].id,a[i].id);
      end;
end;

function check(x,y,jiang:longint):boolean;
begin
  if x>y then
    begin
      if jiang<>0 then exit(true)
                  else exit(false);
    end;
  if (c[x].s=0) then exit(check(x+1,y,jiang));
    if (c[x].s=1) then
      begin
        if (c[x+1].op=c[x].op) and (c[x+1].num=c[x].num+1) and (c[x+1].s>0) and (c[x+2].op=c[x].op) and (c[x+2].num=c[x].num+2) and (c[x+2].s>0) and (x+2<=y) then
          begin
            dec(c[x].s); dec(c[x+1].s); dec(c[x+2].s);
            if (check(x+1,y,jiang)) then exit(true);
            inc(c[x].s); inc(c[x+1].s); inc(c[x+2].s);
          end
      end else
      if (c[x].s=2) then
        begin
          if (jiang=0) then
            if (check(x+1,y,1)) then exit(true);
          if (c[x+1].op=c[x].op) and (c[x+1].num=c[x].num+1) and (c[x+1].s>1) and (c[x+2].op=c[x].op) and (c[x+2].num=c[x].num+2) and (c[x+2].s>1) and (x+2<=y) then
            begin
              dec(c[x].s,2); dec(c[x+1].s,2); dec(c[x+2].s,2);
              if (check(x+1,y,jiang)) then exit(true);
              inc(c[x].s,2); inc(c[x+1].s,2); inc(c[x+2].s,2);
            end;
        end else
        if (c[x].s=3) then
          begin
            if (jiang=0) then
              begin
                dec(c[x].s,2);
                if (check(x,y,1)) then exit(true);
                inc(c[x].s,2);
              end;
            if (check(x+1,y,jiang)) then exit(true);
          end else
          begin
            if (jiang=0) then
              begin
                dec(c[x].s,2);
                if (check(x,y,1)) then exit(true);
                inc(c[x].s,2);
              end;
            dec(c[x].s,3);
            if (check(x,y,jiang)) then exit(true);
            inc(c[x].s,3);
            if (c[x+1].op=c[x].op) and (c[x+1].num=c[x].num+1) and (c[x+1].s>3) and (c[x+2].op=c[x].op) and (c[x+2].num=c[x].num+2) and (c[x+2].s>3) and (x+2<=y) then
              begin
                dec(c[x].s,2); dec(c[x+1].s,2); dec(c[x+2].s,2);
                if (check(x+1,y,jiang)) then exit(true);
                inc(c[x].s,2); inc(c[x+1].s,2); inc(c[x+2].s,2);
              end;
          end;
  exit(false);
end;

function find(n,x,y:longint):longint;
var
  i,j,ans:longint;
begin
  fillchar(use,sizeof(use),0);
  ans:=0;
  for i:=1 to n do
    begin
      if (use[b[i].op,b[i].num]=0) then
        use[b[i].op,b[i].num]:=1;
      for j:=1 to n do
        c[j]:=b[j];
      inc(c[i].s);
      if (ans<0) then ans:=0;
      if (check(1,n,0)) then ans:=ans+4-b[i].s;
      if (use[b[i].op,b[i].num+1]=0) and ((b[i+1].op<>b[i].op) or (b[i+1].num<>b[i].num+1)) and (b[i].num+1<=9) then
        begin
          use[b[i].op,b[i].num+1]:=1;
          for j:=1 to n do
            c[j]:=b[j];
          c[n+1].op:=b[i].op;
          c[n+1].num:=b[i].num+1;
          c[n+1].s:=1;
          qsort(1,n+1,c);
          if (check(1,n+1,0)) then
            begin
              inc(ans,4);
              if (b[i].op=x) and (b[i].num+1=y) then dec(ans);
            end;
        end;
      if (use[b[i].op,b[i].num-1]=0) and ((b[i-1].op<>b[i].op) or (b[i-1].num<>b[i].num-1)) and (b[i].num-1>0) then
        begin
          use[b[i].op,b[i].num-1]:=1;
          for j:=1 to n do
            c[j]:=b[j];
          c[n+1].op:=b[i].op;
          c[n+1].num:=b[i].num-1;
          c[n+1].s:=1;
          qsort(1,n+1,c);
          if (check(1,n+1,0)) then
            begin
              inc(ans,4);
              if (b[i].op=x) and (b[i].num-1=y) then dec(ans);
            end;
        end;
    end;
  exit(ans);
end;

procedure main;
var
  i,j,w:longint;
begin
  num:=0; sum:=0;
  for i:=1 to n do
    begin
      for j:=1 to n do
        b[j]:=a[j];
      dec(b[i].s);
      m:=n;
      if b[i].s=0 then
        begin
          b[i].op:=4;
          dec(m);
          qsort(1,n,b);
        end;
      w:=find(m,a[i].op,a[i].num);
      if (w>=sum) then
        begin
          if w=sum then num:=min(num,a[i].id)
                   else num:=a[i].id;
          sum:=w;
        end;
    end;
end;

begin
  init;
  qsort(1,14,a);
  try1;
  qsort(1,14,a);
  main;
  write(num,' ',sum);
end.


原文地址:https://www.cnblogs.com/zyx-crying/p/9319545.html