贴nescafe 26 div2两道程序

Rainbow的信号(div1)

描述 Description
Freda发明了传呼机之后,rainbow进一步改进了传呼机发送信息所使用的信号。由于现在是数字、信息时代,rainbow发明的信号用N个自然数表示。为了避免两个 人的对话被大坏蛋VariantF偷听T_T,rainbow把对话分成A、B、C三部分,分别用a、b、c三个密码加密。现在Freda接到了 rainbow的信息,她的首要工作就是解密。Freda了解到,这三部分的密码计算方式如下:
在1~N这N个数中,等概率地选取两个数l、r,如果l>r,则交换l、r。把信号中的第l个数到第r个数取出来,构成一个数列P。
A部分对话的密码是数列P的xor和的数学期望值。xor和就是数列P中各个数异或之后得到的数; xor和的期望就是对于所有可能选取的l、r,所得到的数列的xor和的平均数。
B部分对话的密码是数列P的and和的期望,定义类似于xor和。
C部分对话的密码是数列P的or和的期望,定义类似于xor和。

输入格式 InputFormat
第一行一个正整数N。
第二行N个自然数,表示Freda接到的信号。

输出格式 OutputFormat
一行三个实数,分别表示xor和、and和、or和的期望,四舍五入保留3位小数,相邻两个实数之间用一个空格隔开。

样例输入 SampleInput
样例输入1
2
4 5

样例输入2
3
1 0 1

样例输出 SampleOutput 
样例输出1
2.750 4.250 4.750

样例输出2
0.667 0.222 0.889

数据范围和注释 Hint
数据范围与约定
对于20%的数据,1<=N<=100。
对于40%的数据,1<=N<=1000。
对于另外30%的数据,N个数为0或1。
对于100%的数据,1<=N<=100000,N个自然数均不超过10^9。

样例解释
样例1共包含四种可能的l、r:
l, r xor和 and和 or和
1,1    4     4     4
1,2    1     4     5
2,1    1     4     5
2,2    5     5     5
以上每一对l、r出现的概率均相同,因此分别对xor和、and和、or和取平均数就是数学期望值。

时间限制 TimeLimitation
各个测试点1s

 

program P2021;


Var
 f,pre0,pre1:array[0..31,0..100000] of longint;
 a:array[0..100000,0..31] of integer;
 n,i,j,x,oddt,oddf:longint;
 ct:qword;
 ans:extended;

Procedure swap(var p,q:longint);
var
 y:longint;
  begin
  y:=p;
  p:=q;
  q:=y;
end;

Procedure fopen;
  begin
  assign(input,'p2021.in');
  assign(output,'p2021.out');
  reset(input);
  rewrite(output);
end;

Procedure fclose;
  begin
  close(input);
  close(output);
end;

  begin
  fopen;
  readln(n);
  for i:=1 to n do
    begin
    read(x);
    ct:=-1;
    while x<>0 do
      begin
      inc(ct);
      inc(a[i,ct],x mod 2);
      x:=x div 2;
    end;
  end;


  for i:=0 to 31 do
    for j:=2 to n do
      if a[j-1,i]=0 then pre0[i,j]:=j-1 else
        pre0[i,j]:=pre0[i,j-1];

  for i:=0 to 31 do
    for j:=2 to n do
      if a[j-1,i]=1 then pre1[i,j]:=j-1 else
      pre1[i,j]:=pre1[i,j-1];

  {for i:=0 to 17 do
    begin
    for j:=1 to n do
      write(pre0[i,j],' ');
    writeln;
  end;      }


  readln;

  ans:=0;
  for i:=0 to 31 do
    begin
    ct:=0;
    //odd  T
     oddt:=0;
    //odd F
    oddf:=0;
    if a[1,i]=1 then ct:=1;
    for j:=2 to n do
      begin

      if a[j-1,i]=1 then
        begin
        swap(oddt,oddf);
        inc(oddt);
      end else
        inc(oddf);

      if a[j,i]=1 then
        inc(ct,2*oddf+1) else inc(ct,2*oddt);
    end;
    ans:=ans+(ct/(qword(n)*qword(n)))*qword((1 shl i));
  end;
  write(ans:0:3,' ');

  ans:=0;
  for i:=0 to 31 do
    begin
    ct:=0;
    for j:=1 to n do
      if a[j,i]=1 then
       ct:=ct+2*(j-1-pre0[i,j])+1;
      // writeln('I=',i,' J=',j,' pre=',pre0[i,j]);
    //writeln('I=',i,' AND CT=',ct);
    ans:=ans+ct/(qword(n)*qword(n))*qword((1 shl i));
  end;

  write(ans:0:3,' ');

  ans:=0;
  for i:=0 to 31 do
    begin
    ct:=0;
      for j:=1 to n do
        if a[j,i]=1 then inc(ct,2*(j-1)+1) else
          inc(ct,2*pre1[i,j]);
   // writeln('I=',i,' OR CT=',ct);
    ans:=ans+ct/(qword(n)*qword(n))*qword((1 shl i));
  end;

  writeln(ans:0:3);
  fclose;
end.

 

P2022 - Freda的队列

描述 Description
Freda有一个队列,最初它是空的。
现在Freda接到了一系列指令,每个指令包含一个整数x。
如果x>0,表示在队列开头加入一个数x。
如果x=0,表示把队列复制一份,并接在现有队列的末尾。
如果x=-1,表示弹出队列头部的数,并输出这个数值。
但是指令实在是太多了,Freda实在是计算不过来每次要输出什么数值,请你帮帮她吧。
输入格式 InputFormat
第一行包含一个整数N,表示指令的个数。
接下来N行每行一个整数x,描述每条指令。
输出格式 OutputFormat
对于每条x=-1的指令,若此时队列不为空,则输出一个整数,表示从队头弹出的数。否则不进行任何操作。
样例输入 SampleInput 
8
3
4
0
-1
-1
-1
-1
1
样例输出 SampleOutput
4
3
4
3
数据范围和注释 Hint
对于50%的数据,1<=N<=1000.
对于100%的数据,1<=N<=10^6,-1<=x<=10^9。
时间限制 TimeLimitation
各个测试点1s

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

program p2022;

Var
 n,i,j,x,p,q:longint;
 a:array[-4000000..4000000] of longint;

Procedure fopen;
  begin
  assign(input,'p2022.in');
  assign(output,'p2022.out');
  reset(input);
  rewrite(output);
end;

Procedure fclose;
  begin
  close(input);
  close(output);
end;

  begin
  fopen;
  p:=1;q:=0;
  readln(n);
  for i:=1 to n do
    begin
    readln(x);
    if x>0 then
      begin
      dec(p);
      a[p]:=x;
    end;
    if x=0 then
      if (q-p<=1000000) and (q>=p) then
        begin
        for j:=1 to q-p+1 do
          a[q+j]:=a[p+j-1];
        q:=q+q-p+1;
      end;
    if x<0 then
      if q>=p then
        begin
        writeln(a[p]);
        inc(p);
      end;
  end;
  fclose;
end.

 

转载于:https://www.cnblogs.com/htfy/archive/2012/10/26/2741167.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值