HZOI无压力400分之水题长信心模拟赛

题目名称

问题1

问题2

一元三次方程的解

False or true

输入文件

Problem1.in

Problem2.in

equation.in

fot.in

输出文件

Problem1.out

Problem2.out

equation.out

fot.out

测试点数目

10

10

10

10

测试点分数

10

10

10

10

题目类型

传统

传统

传统

传统

时间限制

1s

2s

0.1s

1s

空间限制

128MB

128MB

128MB

128MB

题目很水,自己把握,400分就好了。

1.Problem1

首先,读入一个数n,n代表了下面的操作数,从第2至第n+1 行,每行有一个字符ch和一个数字q,若数字为i,代表将数字q加入数字序列中;若数字为f,代表让你找到数字序列中第q大的数字为多少(保证序列中至少为q个数字,即不会出现误解的情况)。

输入样例:

2

i 1

f 1

输出样例

1

50%数据,n<=5000;

100%数据 n<=250000

 

 

program problem1;
type
  link=^rec;
  rec=record
  lch,rch:link;
  lnum,rnum,heap,data:longint;
  end;
var
  tree:link;
  i,n,ans,x:longint;
  c:char;
procedure right(var tree:link);
  var
    p:link;
  begin
    p:=tree^.lch;
    tree^.lch:=p^.rch;
    if (tree^.lch<>nil) then
      tree^.lnum:=p^.rnum
      else tree^.lnum:=0;
    p^.rch:=tree;
    p^.rnum:=tree^.rnum+tree^.lnum+1;
    tree:=p;
  end;
procedure left(var tree:link);
  var
    p:link;
  begin
    p:=tree^.rch;
    tree^.rch:=p^.lch;
    if (tree^.rch<>nil) then
      tree^.rnum:=p^.lnum
      else tree^.rnum:=0;
    p^.lch:=tree;
    p^.lnum:=tree^.rnum+tree^.lnum+1;
    tree:=p;
  end;
procedure insert(var tree:link;x:longint);
  begin
    if (tree=nil) then
      begin
        new(tree);
        tree^.data:=x;
        tree^.heap:=random(214748364);
        tree^.lch:=nil;
        tree^.rch:=nil;
        tree^.lnum:=0;
        tree^.rnum:=0;
      end
    else
      begin
        if (x<tree^.data) then
          begin
            insert(tree^.lch,x);
            inc(tree^.lnum);
            if (tree^.lch^.heap<tree^.heap) then right(tree);
          end
          else
            begin
              insert(tree^.rch,x);
              inc(tree^.rnum);
              if (tree^.rch^.heap<tree^.heap) then left(tree);
            end;
      end;
  end;
procedure search(tree:link;k:longint);
  begin
    if (tree=nil) then exit;
    if (tree^.lnum=k-1) then
      begin
        ans:=tree^.data;
        exit;
      end
      else
        if (tree^.lnum>=k) then search(tree^.lch,k)
      else
        search(tree^.rch,k-1-tree^.lnum);
  end;
begin
  assign(input,'problem1.in');reset(input);
  assign(output,'problem1.out');rewrite(output);
  randomize;
  readln(n);
  tree:=nil;
  for i:=1 to n do
    begin
      readln(c,x);
      if (c='i') then
        begin
          insert(tree,x);
        end
        else
        begin
          search(tree,x);
          writeln(ans);
        end;
    end;
  close(input);
  close(output);
end.

2.problem2

给定一个01背包和n个物品,求有多少种选择方法使得背包再也放不下余下的任意物品。

输入格式

第一行一个数字q,表示有q组测试数据

对于每一组测试数据第一行有两个数字n和m,n表示物品的个数,m表示背包的体积,下一行中有n个数字V1..VN分别表示每件物品的体积。

输出格式:

一个数字,sum表示不能使背包再放入任何物品的方案数。(保证不大于maxlongint)

输入格式:

  2

6 25

8 9 8 7 16 5

30 250

1 2 3 4 5 6 7 8 9 10 11

12 13 14 15 16 17 18 19 20

21 22 23 24 25 26 27 28 29 30

输出格式
15

16509438

数据范围:

对于100%的数据,q<=1000,n<=30,m<=1000;

对于每一个vi,保证vi<=1000;

 

program problem2;
var
  f:array[0..20000]of longint;
  a,s:array[0..40]of longint;
  i,j,k,l,m,n,ans,q:longint;
procedure sort(l,r:longint);
  var
    i,j,x,y:longint;
  begin
    i:=l;
    j:=r;
    x:=a[(l+r) shr 1];
    repeat
      while (a[i]<x) do inc(i);
      while (a[j]>x) do dec(j);
      if (i<=j) then
        begin
          y:=a[i];
          a[i]:=a[j];
          a[j]:=y;
          inc(i);
          dec(j);
        end;
    until i>j;
    if (i<r) then sort(i,r);
    if (l<j) then sort(l,j);
  end;
begin
  assign(input,'problem2.in');reset(input);
  assign(output,'problem2.out');rewrite(output);
  readln(q);
  for l:=1 to q do
    begin
      read(n,m);
      ans:=0;
      for i:=1 to n do
        begin
          read(a[i]);
        end;
      readln;
      sort(1,n);
      fillchar(s,sizeof(s),0);
      for i:=1 to n do s[i]:=s[i-1]+a[i];
      for k:=1 to n do
        begin
          fillchar(f,sizeof(f),0);
          f[s[k-1]]:=1;
          for i:=k+1 to n do
            for j:=m downto a[i]+s[k-1] do
              begin
                inc(f[j],f[j-a[i]]);
              end;
		  for j:=m downto m-a[k]+1 do inc(ans,f[j]);
        end;
      writeln(ans);
    end;
  close(input);close(output);
end.

 

3.一元三次方程求解

有形如:ax^3+bx^2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-10000至10000之间),且根与根之差的绝对值>=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后4位。

输入格式

一行4个实数,分别表示三次项系数,二次项系数,一次项系数,常数项(每个的系数均保证绝对值在10^9以内)

输出格式

一行三个实数,为方程的3个实根,精确到小数点后4位

输入样例

1 0 -1 0

输出样例

-1.0000 0.0000 1.0000

 

program equation;
var
  a,b,c,d,now,last,l,r,mid,ta,tb:extended;
  num,i,tot:longint;
  s:array[0..5]of extended;
  esp:extended;
  x,y:array[0..4]of extended;
function getnum(x:extended):extended;
  var
    t:extended;
  begin
    t:=a*x*x*x+b*x*x+c*x+d;
    exit(t);
  end;
procedure sort(l,r:longint);
  var
    i,j:longint;
    x,y:extended;
  begin
    i:=l;
    j:=r;
    x:=s[(l+r) shr 1];
    repeat
      while s[i]<x do inc(i);
      while s[j]>x do dec(j);
      if (i<=j) then
        begin
          y:=s[i];
          s[i]:=s[j];
          s[j]:=y;
          inc(i);
          dec(j);
        end;
    until i>j;
    if (i<r) then sort(i,r);
    if (l<j) then sort(l,j);
  end;
begin
  assign(input,'equation.in');reset(input);
  assign(output,'equation.out');rewrite(output);
  readln(a,b,c,d);
  esp:=0.000001;
  last:=maxlongint;
  for i:=-10000 to 10000 do
    begin
      now:=getnum(extended(i));
      if (now=0) then
        begin
          inc(num);
          s[num]:=i;
        end
        else
        if (last<>maxlongint) then
          begin
            if (last*now<0) then
              begin
                inc(tot);
                x[tot]:=i-1;
                y[tot]:=i;
              end;
          end;
      last:=now;
    end;
  for i:=1 to tot do
    begin
      l:=x[i];
      r:=y[i];
      while (l+esp<r) do
        begin
          mid:=(l+r)/2;
          ta:=getnum(l);
          tb:=getnum(mid);
          if (ta*tb<0) then r:=mid else l:=mid;
        end;
      inc(num);
      s[num]:=l;
    end;
  sort(1,3);
  writeln(s[1]:0:4,' ',s[2]:0:4,' ',s[3]:0:4);
  close(input);
  close(output);
end.

 

4.false or true

平面上,一个圆,圆的边上按顺时针放着n个点。现在要连m条边,比如a,b,那么a到b可以从圆的内部连接,也可以从圆的外部连接。问能不能连接这m条边,使这些边都不相交。(比如两条边分别是1-2,2-3,则可以连接。若有三条边分别时1-5,2-6,3-7则一定会出现相交)。

输入数据会有多组:防止骗分

对于每一组输入数据,如果可以存在的话,则输出true,如果不能存在的话,则输出false

输入格式:

第一行一个数q,表示数据的组数。

对于每组数据,第一行为两个数n和m,n指点的个数,m指要连的边的个数。

2..m+1行,每行两个数字a,b表示要连的边的两个端点。

输出格式

若可以,则输出true,否则,输出false。

输入样例

1

4 2

0 1

3 2

输出样例

true

100%数据,q<=30,n<=1000,m<=100;

 

var
  x,y:array[0..1100]of longint;
  wx,wy,nx,ny:array[0..1100]of longint;
  i,j,t,n,m,p,tmp,totw,totn,tot:longint;
  flag1,flag2:boolean;
procedure sort(l,r:longint);
  var
    i,j,a,b,c:longint;
  begin
    i:=l;
    j:=r;
    a:=x[(l+r) shr 1];
    b:=y[(l+r) shr 1];
    repeat
      while (y[i]<b)or((y[i]=b)and(x[i]>a)) do inc(i);
      while (y[j]>b)or((y[j]=b)and(x[j]<a)) do dec(j);
      if (i<=j) then
        begin
          c:=x[i];
          x[i]:=x[j];
          x[j]:=c;
          c:=y[i];
          y[i]:=y[j];
          y[j]:=c;
          inc(i);
          dec(j);
        end;
    until i>j;
    if (i<r) then sort(i,r);
    if (l<j) then sort(l,j);
  end;
procedure wai(t:longint);
  begin
    while (wy[t]<=y[i])and(wx[t]>=x[i])and(t>0) do dec(t);
    if (t=0)or(x[i]>=wy[t]) then
      begin
        inc(totw);
        wx[totw]:=x[i];
        wy[totw]:=y[i];
      end
      else flag1:=true;
  end;
procedure nei(t:longint);
  begin
    while (ny[t]<=y[i])and(nx[t]>=x[i])and(t>0) do dec(t);
    if (t=0)or(x[i]>=ny[t]) then
      begin
        inc(totn);
        nx[totn]:=x[i];
        ny[totn]:=y[i];
      end
      else flag2:=true;
  end;
begin
  assign(input,'fot.in');reset(input);
  assign(output,'fot.out');rewrite(output);
  readln(t);
  for p:=1 to t do
    begin
      readln(n,m);
      for i:=1 to m do
        begin
          readln(x[i],y[i]);
          if (x[i]>y[i]) then
            begin
              tmp:=x[i];
              x[i]:=y[i];
              y[i]:=tmp;
            end;
        end;
      sort(1,m);
      tot:=0;
      totw:=0;
      totn:=0;
      fillchar(nx,sizeof(nx),0);
      fillchar(ny,sizeof(ny),0);
      fillchar(wx,sizeof(wx),0);
      fillchar(wy,sizeof(wy),0);
      for i:=1 to m do
        begin
          flag1:=false;
          flag2:=false;
          wai(totw);
          if (flag1) then nei(totn);
          if (not flag1)or(not flag2) then inc(tot);
        end;
      if (tot=m) then writeln('true') else writeln('false');
    end;
  close(input);close(output);
end.