jzoj2563 区间运算

    xiaoxiao2026-01-11  7

    又是万恶的表达式解析.

    用了黑科技: 首先用栈把括号给去掉,把区间给提取出来单独存然后用’$’ 代替

    处理的时候就可以根据这是第几个’$’来处理, 其他数也是等价的

    程序打了一个小时,不过我自己认为打的还是挺优美的.

    DEMO

    type str_=string; sec=record l,r:double; end; var ex:str_; i,j,k:longint; tmp:sec; no0:boolean; function max(a,b:double):double; begin if(a>b) then exit(a) else exit(b); end; function min(a,b:double):double; begin if(a>b) then exit(b) else exit(a); end; function copy0(ex:str_; be,ed:longint):str_; begin exit(copy(ex,be,ed-be+1)); end; function pos0(ex:str_;be:longint;target:char):longint; var i:longint; begin for i:=be to length(ex) do if ex[i]=target then exit(i); exit(0); end; function lastchar(str:str_; loc:longint):char; var j:longint; begin for j:=loc-1 downto 1 do if (str[j]<>'#') then exit(str[j]); end; //格式: 数1,数2 function toSec(ex:str_):sec; var i:longint; rs:sec; begin for i:=1 to length(ex) do if (ex[i]=',') then begin val(copy(ex,1,i-1),rs.l); val(copy(ex,i+1,length(ex)),rs.r); exit(rs); end; end; function toString(x:sec):str_; var s1,s2:str_; begin str(x.l,s1); str(x.r,s2); exit('['+s1+','+s2+']'); end; procedure not0(var x:sec); var l,r:double; begin l:=min(-x.l,-x.r); r:=max(-x.l,-x.r); x.l:=l; x.r:=r; end; function mul(a,b:sec):sec; var rs:sec; begin rs.l:=min(a.l*b.l,min(a.l*b.r,min(a.r*b.l,a.r*b.r))); rs.r:=max(a.l*b.l,max(a.l*b.r,max(a.r*b.l,a.r*b.r))); exit(rs); end; function divi(a,b:sec):sec; var rs:sec; begin if (b.l<=0)and(b.r>=0) then begin no0:=true; exit(a); end; rs.l:=min(a.l/b.l,min(a.l/b.r,min(a.r/b.l,a.r/b.r))); rs.r:=max(a.l/b.l,max(a.l/b.r,max(a.r/b.l,a.r/b.r))); exit(rs); end; function add(a,b:sec):sec; var rs:sec; begin rs.l:=min(a.l+b.l,min(a.l+b.r,min(a.r+b.l,a.r+b.r))); rs.r:=max(a.l+b.l,max(a.l+b.r,max(a.r+b.l,a.r+b.r))); exit(rs); end; function minus(a,b:sec):sec; var rs:sec; begin rs.l:=min(a.l-b.l,min(a.l-b.r,min(a.r-b.l,a.r-b.r))); rs.r:=max(a.l-b.l,max(a.l-b.r,max(a.r-b.l,a.r-b.r))); exit(rs); end; function decode(ex:str_):sec; var st:array[0..100] of sec; //stack:array[0..100] of char; bloc,th,stot,top:longint; isnotsec,last,k,j,i:longint; loc:array[0..100] of longint; pre,suf,stack,tmpp:str_; tmp,rs,part:sec; begin rs.l:=0; rs.r:=0; if (no0) then exit(rs); stack:='000000000000000000000000000000000000000000000'; //fillchar(stack,sizeof(stack),0); fillchar(st,sizeof(st),0); top:=0; stot:=0; i:=1; //解析括号与区间 while (i<=length(ex)) do begin if (ex[i]=')') then begin tmpp:=''; for j:=top downto 1 do begin dec(top); if (stack[j]='(') then begin bloc:=loc[j]; break; end; if (stack[j]='$') then dec(stot); end; tmp:=decode(copy0(ex,bloc+1,i-1)); pre:=copy0(ex,1,bloc-1)+toString(tmp); suf:=copy0(ex,i+1,length(ex)); i:=length(pre); ex:=pre+suf; inc(top); stack[top]:='$'; inc(stot); st[stot]:=tmp; end else if (ex[i]='[') then begin k:=pos0(ex,i,']'); inc(stot); st[stot]:=toSec(copy0(ex,i+1,k-1)); inc(top); stack[top]:='$'; loc[top]:=i; i:=k; end else begin inc(top); stack[top]:=ex[i]; loc[top]:=i; end; inc(i); end; //取反 th:=0; for i:=1 to top do begin if (stack[i]='$') then inc(th); if (stack[i]='-') then begin if(stack[i+1]='$')and(stack[i-1]<>'$') then begin not0(st[th+1]); stack[i]:='#'; end; end; end; //乘除 加减 part.l:=-maxlongint; part.r:=0; th:=0; last:=1; for i:=1 to top do begin if (stack[i]='#') then continue; if (stack[i]='$') then begin stack[i]:='#'; inc(th); if (part.l=-maxlongint) then part:=st[th] else begin if (lastchar(stack,i)='*') then part:=mul(part,st[th]); if (lastchar(stack,i)='/') then part:=divi(part,st[th]); stack[i-1]:='#'; end; end; if (stack[i]='+')or(stack[i]='-') then begin if (last=1) then rs:=add(rs,part) else rs:=minus(rs,part); if (stack[i]='+') then last:=1 else last:=-1; part.l:=-maxlongint; part.r:=0; end; end; if (last=1)and(part.l<>-maxlongint) then rs:=add(rs,part) else rs:=minus(rs,part); exit(rs); end; begin assign(input,'2563.in'); reset(input); while (not eof) do begin no0:=false; readln(ex); tmp:=decode(ex); if (no0=false) then writeln('[',tmp.l:0:3,',',tmp.r:0:3,']') else writeln('Division by zero'); end; end.
    转载请注明原文地址: https://ju.6miu.com/read-1305886.html
    最新回复(0)