zoukankan      html  css  js  c++  java
  • 【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题不久就会成为黑题

    后排鸣谢@找寻 大佬

  • 相关阅读:
    Timestamp,Date和String的互相转换
    从网址截取域名
    $.ajax()方法详解
    JS正则表达式详解
    List、Set、Map集合的遍历方法
    spring-security2配置精讲(转载)
    spring-security原理学习
    spring-security配置和原理简介
    三步法搞定CTF中的SQL注入题型
    两个局域网(办公网-IDC)安全互通方案2:by GRE and linux server&深入理解GRE
  • 原文地址:https://www.cnblogs.com/vercont/p/10210111.html
Copyright © 2011-2022 走看看