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

mac2022-06-30  80

前排鸣谢@找寻 大佬

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\n",ans); } else { puts("No"); printf ("%d\n",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题不久就会成为黑题

后排鸣谢@找寻 大佬

转载于:https://www.cnblogs.com/vercont/p/10210111.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)