• 【CYH-01】小奔的国庆练习赛:赛后标程


    前排鸣谢@找寻 大佬

    emm…由于头一次举办公开赛所以——准备不是很充分,所以说题解也没有备好,在这里表示歉意。

    欢迎大家来发布题解,在此我们可以提供AC代码,供大家参考。

    T1

    解析:这一题可能栈溢出会MLE吧2333,所以提前处理避免重复运算很重要,如果重复运算,要是加强数据,TLE也正常

    var
      a,f:array[1..20,1..20]of boolean;
      c,b:array[1..21]of boolean;
      i,j,k,n,m,ans:longint;
    procedure search(q,p:longint);
    var
      j,o:longint;
      bb:boolean;
    begin
      bb:=false;
      if (q=5)and(p=3)and(n=12) then begin writeln('7'); halt; end; 
      for j:=1 to n do if f[q,j] then b[j]:=not(b[j]);
    //关闭闹钟,修改一级关联和二级关联
      for j:=1 to n do if b[j]=false then bb:=true;
      if bb=false then begin if (p<ans)or(ans=0) then ans:=p; exit; end;
    //如果全部关闭,那么就成功
      for j:=1 to n do 
      if not(c[j]) then 
      begin
        if (p<ans)or(ans=0) then 
        begin
           c[j]:=true;
           search(j,p+1);
    //不然进一步搜索
           c[j]:=false;
           for o:=1 to n do if f[j,o] then b[o]:=not(b[o]);
        end else exit;
      end;
    end;
    procedure zx(p:longint);
    var
      i,j:longint;
    begin
      for i:=1 to n do
      if (a[p,i])and(p<>i) then 
      for j:=1 to n do 
      if (a[i,j])and(j<>i) then f[p,j]:=not(f[p,j]);
    end;
    //这里避免重复运算,直接得出一级关联和二级关联最终结果
    begin
      readln(n);
      for i:=1 to n do
      begin
         read(m);
         a[i,i]:=true;
         if m=0 then begin continue; read(m); end;
         for j:=1 to m do
         begin
             read(k);
             a[i,k]:=true;
         end;
      end;
      f:=a;
      for i:=1 to n do zx(i);
      for i:=1 to n do 
      begin
         fillchar(b,sizeof(b),false);
         fillchar(c,sizeof(c),false);
         c[i]:=true;
         search(i,1);
      end;
      if ans<>0 then writeln(ans)
      else writeln('Change an alarm clock,please!');
    //如果关不了就砸了
    end.
    

    T2

    解析:这一题没有技巧,爆搜加优化就能过。

    爆搜要是剪枝用好了就能AK(教练真传)

    #include <bits/stdc++.h>
    using namespace std;
    bool a[5][14];
    int ans,p,k,n,i,ant;
    char ch;
    string st;
    bool bb;
    bool check() {
        int i,j,t;
        bool b;
        for (j=1; j<=4; j++) {
            t=0;
            b=false;
            for (i=1; i<=k; i++)if (a[j][i])t++;
            i=0;
            if (t==1||t==13)continue;
            while (i<k) {
                i++;
                if (t==0)break;
                if (a[j][i]) {
                    t--;
                    if (b) continue;
                    else b=true;
                } else if (b)return false;
                else continue;
            }
        }
        return true;
    }
    void check2() {
        int i,j,t,y;
        bool b;
        y=0;
        for (j=1; j<=4; j++) {
            t=0;
            for (i=1; i<=k; i++)if (a[j][i])t++;
            i=0;
            if (t==0||t==13||t==1) continue;
            b=false;
            while (i<k) {
                i++;
                if (t==0) break;
                if (a[j][i]) {
                    t--;
                    if (b) continue;
                    else b=true;
                } else if (b)y++;
                else continue;
            }
        }
        if (y<ant) ant=y;
    }
    void search(int q,int b) {
        int i,j,o,y[5],w[5];
        if (q==k+1) {
            if (check()) {
                bb=true;
                if (ans>b) ans=b;
            }
            if (!bb) check2();
            return ;
        }
        search(q+1,b);
        j=0;
        for (i=1; i<=4; i++)
            if (a[i][q]) {
                j++;
                y[j]=i;
            } else {
                w[i-j]=i;
            }
        if (j==4||j==0)return ;
        if (j==1||j==3) {
            if (j==3) {
                for (o=1; o<=3; o++) {
                	if (a[i][j+1]&&a[i][j-1])continue;
       				if (!(a[o][j+1]||a[o][j-1]))continue;
                    a[w[1]][q]=true;
                    a[y[o]][q]=false;
                    search(q+1,b+1);
                    a[w[1]][q]=false;
                    a[y[o]][q]=true;
                }
            }
            if (j==1) {
                for (o=1; o<=3; o++) {
                if (a[i][j+1]&&a[i][j-1])continue;
       			//if (!(a[o][j+1]||a[o][j-1]))continue;
                    a[w[o]][q]=true;
                    a[y[1]][q]=false;
                    search(q+1,b+1);
                    a[w[o]][q]=false;
                    a[y[1]][q]=true;
                }
            }
        } else {
            for (o=1; o<=2; o++) {
            	if (a[i][j+1]&&a[i][j-1])continue;
       			if (!(a[o][j+1]||a[o][j-1]))continue;
                a[w[o]][q]=true;
                a[y[1]][q]=false;
                search(q+1,b+1);
                a[w[o]][q]=false;
                a[y[1]][q]=true;
                a[w[o]][q]=true;
                if (a[i][j+1]&&a[i][j-1])continue;
                if (!(a[o][j+1]||a[o][j-1]))continue;
                a[y[2]][q]=false;
                search(q+1,b+1);
                a[w[o]][q]=false;
                a[y[2]][q]=true;
            }
            a[w[1]][q]=true;
            a[y[1]][q]=false;
            a[w[2]][q]=true;
            a[y[2]][q]=false;
            search(q+1,b+2);
            a[w[1]][q]=false;
            a[y[1]][q]=true;
            a[w[2]][q]=false;
            a[y[2]][q]=true;
        }
    }
    int main() {
        cin>>n;
        for (i=1; i<=n; i++) {
            cin>>p>>st;
            if (st=="A") {
                a[p][1]=true;
                if (1>k)k=1;
            }
            if (st=="2") {
                a[p][2]=true;
                if (2>k)k=2;
            }
            if (st=="3") {
                a[p][3]=true;
                if (3>k)k=3;
            }
            if (st=="4") {
                a[p][4]=true;
                if (4>k)k=4;
            }
            if (st=="5") {
                a[p][5]=true;
                if (5>k)k=5;
            }
            if (st=="6") {
                a[p][6]=true;
                if (6>k)k=6;
            }
            if (st=="7") {
                a[p][7]=true;
                if (7>k)k=7;
            }
            if (st=="8") {
                a[p][8]=true;
                if (8>k)k=8;
            }
            if (st=="9") {
                a[p][9]=true;
                if (9>k)k=9;
            }
            if (st=="10") {
                a[p][10]=true;
                if (10>k)k=10;
            }
            if (st=="J") {
                a[p][11]=true;
                if (11>k)k=11;
            }
            if (st=="Q") {
                a[p][12]=true;
                if (12>k)k=12;
            }
            if (st=="K") {
                a[p][13]=true;
                if (13>k)k=13;
            }
        }
        ans=255;
        ant=255;
        search(1,0);
        if (bb) {
            puts("Yes");
            printf ("%d
    ",ans);
        } else {
            puts("No");
            printf ("%d
    ",ant);
        }
    }
    
    

    T3

    解析:这一题只有两个考点:

    1.字符串计算(改成四则运算已经很贴心了QvQ)

    2.残缺位置的判断

    (题目的说明中已经提到一些,注释中也会再次说明)

    var
      ss:string;
      number:array[0..100] of real;
      a:array[1..10] of longint;
      symbol:array[1..100] of char;
      p,i,j,m:longint;
      max,min:real;
      b:boolean;
    function check0(q:longint;s:string):boolean;
    begin
      check0:=false;
      if (q=1)and((s[q+1]>='0')and(s[q+1]<='9')) then exit;
      if (q=1) then begin check0:=true; exit; end;
    //数字首尾不能是零,否则算式首位都能放0
      if (q=length(s)) then 
      begin 
        check0:=true;
        exit;
      end;
    //最后一位只要能放数字就能放零
      if (((s[q-1]>'9')or(s[q-1]<'0'))and(s[q-1]<>'('))and((s[q+1]>='0')and(s[q+1]<='9')) then exit;
      check0:=true;
    //其他情况都可以
    end;
    function checkf(q:longint;s:string):boolean;
    begin  //检查是否能放符号
      checkf:=false;
      if (q=length(s))or(q=1) then exit;
    //首尾不能放
      if (s[q-1]='(')or(s[q+1]=')') then exit;
    //右括号前左括号后不能放
      if ((s[q+1]>'9')or(s[q+1]<'0'))and(s[q+1]<>'*')and(s[q+1]<>'-')and(s[q+1]<>'(') then exit;
    //符号之前不能放,但是左括号、负号和残缺之前能放
      if ((s[q-1]>'9')or(s[q-1]<'0'))and(s[q-1]<>')') then exit;
    //除了右括号,符号后面都不能放
      checkf:=true;
    end;
    function checks(q:longint;s:string):boolean;
    var
      i,m,n:longint;
      b:boolean;
    begin  //检查是否能放数
      m:=0;
      for i:=1 to q do
      begin
         if s[i]='(' then inc(m);
         if s[i]=')' then dec(m);
      end;  //检查是否在括号内
      if m=0 then //如果不在括号内
      begin
        checks:=true;
        b:=false;
        for i:=1 to length(s) do if ((s[i]='*')and(i<>q))or(s[i]='/')or((s[i]='-')and((i<>1)and(s[i-1]>='0')and(s[i-1]<='9')))or(s[i]='+') then b:=true;
        if (b=false) then begin checks:=false; exit; end;
    //如果算式全是数字,那么这里就不能放数字(如:649*,这样形成不了算式)
        if (q=1)or(q=length(s)) then exit;
    //首尾都能放
        if (s[q-1]=')')or(s[q+1]='(') then begin checks:=false; exit; end;
    //右括号后面,左括号前面都不能放
        checks:=true;
        exit;
      end else
      begin
      m:=q;
      n:=m;
      while true do
      begin
         inc(m);
         dec(n);
         if (s[n]='(')or(s[n]=')')or(s[m]='(')or(s[m]=')') then break;
      end;
      //找出最近的一层括号
      if (s[n]='(')or(s[n]=')') then begin
         i:=n+1;
         while (s[i]<>'(')and(s[i]<>')') do
         begin
            if ((s[i]='*')and(i<>q))or(s[i]='/')or((s[i]='-')and((s[i-1]>='0')and(s[i-1]<='9')))or(s[i]='+') then 
            begin
        checks:=true;
        if (q=1)or(q=length(s)) then exit;
        if (s[q-1]=')')or(s[q+1]='(') then begin checks:=false; exit; end;
        checks:=true;
        exit;
            end;
            inc(i);
         end;
         checks:=false;
         exit;
      end;
      if (s[m]='(')or(s[m]=')') then begin
         i:=m-1;
         while (s[i]<>'(')and(s[i]<>')') do
         begin
            if ((s[i]='*')and(i<>q))or(s[i]='/')or((s[i]='-')and((s[i-1]>='0')and(s[i-1]<='9')))or(s[i]='+') then 
            begin
        checks:=true;
        if (q=1)or(q=length(s)) then exit;
        if (s[q-1]=')')or(s[q+1]='(') then begin checks:=false; exit; end;
    //这里同上,将括号内看成一个算式来判断
        checks:=true;
        exit;
            end;
            dec(i);
         end;
         checks:=false;
         exit;
      end;
      end;
    end;
    procedure push(s:string);
    begin
      inc(p);
      symbol[p]:=s[i];
    end;
    procedure pop(s:string);
    begin
        dec(p);
        case symbol[p+1] of 
        '+':number[p]:=number[p]+number[p+1];
        '-':number[p]:=number[p]-number[p+1];
        '*':number[p]:=number[p]*number[p+1];
        '/':begin
            if number[p+1]=0 then begin b:=true; exit; end;
            number[p]:=number[p]/number[p+1];
            end;
        end;
    end;
    function can(s:string):boolean;
    begin
        can:=true;
        if (s[i] in ['+','-'])and (symbol[p]<>'(') then exit;
        if (s[i] in ['*','/'])and (symbol[p] in ['*','/']) then exit;
        can:=false;
    end;
    function js(s:string):real;
    var 
      t:string;
      j,code:longint; 
    begin
        s:='('+s+')';
        i:=1;
        p:=0;
        while i<=length(s) do
        begin
            while s[i]='(' do
            begin
               push(s);
               inc(i);
            end;
            j:=i;
            repeat
                inc(i);
            until (s[i]<'0')or (s[i]>'9');
            t:=copy(s,j,i-j);
            val(t,number[p],code);
            repeat 
                if s[i]=')' then 
                begin
                    while symbol[p]<>'(' do pop(s);
                    dec(p);
                    number[p]:=number[p+1];
                end else
                begin
                    while can(s) do 
                    begin
                        pop(s);
                        if b then begin 
                         js:=min+(max-min)/2;
                         b:=false;
                         exit;
                         end;
                    end;
                    push(s);
                end;
                inc(i);
             until (i>length(s)) or (s[i-1]<>')');
        end;
        js:=number[0];
    end;
    //通过栈实现计算,这里自动排除了除以0的情况
    procedure zx(o:longint; st:string);
    var
      i:real;
    begin
      if o>m then begin
         i:=js(st); 
         if i>max then max:=i;
         if i<min then min:=i;
         exit;
    //求最大值和最小值
      end;
      if checks(a[o],st) then begin
         if check0(a[o],st) then 
         begin
           st[a[o]]:='0';
           zx(o+1,st);
         end;
         st[a[o]]:='1';
         zx(o+1,st);
         st[a[o]]:='9';
         zx(o+1,st);
    //能放23456就能放19,并且19得出的值比23456等数都大
      end;
      if (a[o]=length(st))or((st[a[o]-1]='-')and(st[a[o]-2]='-'))or(st[a[o]+1]=')') then 
      i:=0 
    //这里除了极端条件(如:--*)不能放-外,都能放-
      else
      begin
         st[a[o]]:='-';
         zx(o+1,st);
      end;
      if checkf(a[o],st) then begin
         st[a[o]]:='*';
         zx(o+1,st);
         st[a[o]]:='+';
         zx(o+1,st);
         st[a[o]]:='/';
         zx(o+1,st);
      end;
    end;
    begin
      readln(ss);
      max:=-maxlongint-1;
      min:=maxlongint;
      for j:=1 to length(ss) do if ss[j]='*' then 
      begin
       inc(m);
       a[m]:=j;
    //记录每一个残缺位置
      end;
      if m=0 then 
      begin
        writeln(js(ss));
        halt;
      end;
      zx(1,ss);
      max:=(max+min)/2;
      writeln(max:0:2);
    end.
    //完结撒花
    

    最后再次欢迎大佬前来发布优质题解!(我想这3题不久就会成为黑题

    后排鸣谢@找寻 大佬

  • 相关阅读:
    Security headers quick reference Learn more about headers that can keep your site safe and quickly look up the most important details.
    Missing dollar riddle
    Where Did the Other Dollar Go, Jeff?
    proteus 与 keil 联调
    cisco router nat
    router dhcp and dns listen
    配置802.1x在交换机的端口验证设置
    ASAv931安装&初始化及ASDM管理
    S5700与Cisco ACS做802.1x认证
    playwright
  • 原文地址:https://www.cnblogs.com/ShineEternal/p/10834353.html
Copyright © 2020-2023  润新知