zoukankan      html  css  js  c++  java
  • [USACO精选] 第一章 数值计算

    好不容易坑来了传说中的USACO精选,近100题我要是能做完就哈哈哈哈了…继今天学并查集连番受挫之后,决定写一写基础题。

    #0 负二进制 2014-01-10

    其实是想到就会做,不想到就不会做的题,数学渣渣在此,赶紧承认自己看了解题0 0……其实我自己对于负数的mod不是很熟…如果考场上出这种东西自己开个exam.pas弄几个mod负数div负数不就摸索出来了么…

    (其实我最开始的想法是,按正数除,除出来一个2^(2k-1)的就当成(-2)^2k+(-2)^(2k-1))

    program tyvj_p1022;
    var a:array[1..10000] of integer;
        x,i,t:longint;
    begin
      readln(x);
      if x=0 then
        begin
          writeln(0);
          halt;
        end;
      t:=0;
      while x<>0 do
        begin
          inc(t);
          a[t]:=x mod (-2);
          if a[t]<0 then
            begin
              a[t]:=a[t]+2;
              x:=x-2;
            end;
          x:=x div (-2);
        end;
      for i:=t downto 1 do
        write(a[i]);
    end.
    负二进制


    #1 数的幂次 2014-01-10

    一开始还脑残在想这题是不是不用快速幂啊纯模拟啊…结果,写的快速幂+高精度,自己的机器都超时运作了…话说这题被坑了,我拿到的题目上写着答案不超过15000个字符的,结果我201个好久还以为是integer太小了,开成了longint,后来直接qword了… 后来数组开50000就over了…

    不写不知道一写吓一跳噜,写快速幂+高精度要注意:(1)高精度自乘(本程序中采用ti数组)不要一脑残就以为是2在自己乘啊!(2)高精度a[i+j]:=a[i+j-1] div 10啊不要一脑残直接inc(a[i+j])…程序可优化的空间就是,写了两段高精度乘,其实可以弄成两个参数而不要再写一遍的…

    program cruel1;
    var a,ti:array[0..50000] of qword;
        node:array[0..20] of boolean;
        n,p,t,i,tn,t0:longint;
    procedure work_self_times;
    var c:array[0..50000] of qword;
        i,j,t:longint;
    begin
      fillchar(c,sizeof(c),0);
      for i:=1 to ti[0] do
        for j:=1 to ti[0] do
          begin
            c[i+j-1]:=c[i+j-1]+ti[i]*ti[j];
            if c[i+j-1]>9 then
              begin
                c[i+j]:=c[i+j]+c[i+j-1] div 10;
                c[i+j-1]:=c[i+j-1] mod 10;
              end;
          end;
      t:=2*ti[0];
      while c[t]=0 do dec(t);
      c[0]:=t;
      ti:=c;
    end;
    
    procedure times;
    var c:array[0..50000] of qword;
        i,j,t:longint;
    begin
      fillchar(c,sizeof(c),0);
      for i:=1 to a[0] do
        for j:=1 to ti[0] do
          begin
            c[i+j-1]:=c[i+j-1]+a[i]*ti[j];
            if c[i+j-1]>9 then
              begin
                c[i+j]:=c[i+j]+c[i+j-1] div 10;
                c[i+j-1]:=c[i+j-1] mod 10;
              end;
          end;
      t:=2*ti[0];
      while c[t]=0 do dec(t);
      c[0]:=t;
      a:=c;
    end;
    begin
      readln(n,p);
      t:=1;
      while p<>0 do
        begin
          if p mod 2=1 then node[t]:=true;
          p:=p div 2;
          inc(t);
        end;
      fillchar(a,sizeof(a),0); a[1]:=1; a[0]:=1;
      fillchar(ti,sizeof(ti),0);
      t0:=1;tn:=n;
      while tn<>0 do
        begin
          ti[t0]:=tn mod 10;
          tn:=tn div 10;
          inc(t0);
        end;
      ti[0]:=t0-1;
      for i:=1 to t do
        begin
          if node[i]=true then times;
          work_self_times;
        end;
      t:=15000;
      while a[t]=0 do dec(t);
      for i:=t downto 1 do
        write(a[i]);
    end.
    数的幂次

    #2 分数变小数 2014-01-11

    又脑残去搜题解了,结果看到很多大神的博客都说这题神坑,我还以为这题有多么的奇葩… 其实就是除法啦,第一次出错后还莫名其妙想了个要写链表的方法…(那方法其实是错的,但是话说上一次写链表是不知道多少年前了,要练习一下。)

    x是商,x0是余数(多余的,可以不用),mark标记余数是否出现过。output1用于无循环的小数的输出,output2用于循环小数的输出。

    其实有点虚,目测了一下答案是对的,但是数据7和8实在太长了…

    program usaco_3;
    var n,d,z,t,i:longint;
        x,x0:array[0..200000] of longint;
        mark:array[0..100000] of longint;
    procedure output1;
    var i:longint;
    begin
      for i:=0 to t do
        write(x[i]);
      halt;
    end;
    procedure output2(l,r:longint);
    var i:longint;
    begin
      for i:=1 to t do
        begin
          if i=l+1 then write('(');
          write(x[i]);
          if i=r then write(')');
        end;
      halt;
    end;
    
    begin
      readln(n,d);
      z:=n div d;
      n:=n mod d;
      write(z,'.');
      if n=0 then
        begin
          write('0');
          halt;
        end;
      t:=0;
      for i:=1 to 100000 do mark[i]:=-1;
      mark[n]:=0;
      while true do
        begin
          inc(t);
          x0[t]:=n;
          n:=n*10;
          x[t]:=n div d;
          n:=n mod d;
          if n=0 then output1;
          if (mark[n]<>-1) then
            output2(mark[n],t)
          else
            mark[n]:=t;
        end;
    end.
    分数变小数

    #3 丑数 2014-01-12

    之前有两个程序是失败的,两个都是枚举list中的数据而不是p中的素数,导致慢的要死,要知道k的范围是[1,100],n的范围是[1,100000]…第二个稍微加了个小优化,用p0记录以免重复乘。然后默默去看题解…(啊啊啊你怎么能这么不独立呢!)于是开始枚举素数,用p0记录。但是第12个数据点的n=100000貌似还是很慢,这题目前没找到到oj可以测评(没去找…),去网上拉了个题解复制下来看看貌似第12点都超级慢,那就先搁着吧,等我USACO的training做到Chapter 3了去提交一下就知道了…

    BTW快排可以不用写,我拿到的翻译里面没写输入的时候是有序的所以我自作多情地写了一个… T T

    最终的:

    program usaco_3;
    var k,n,i,j,l,t,t0:dword;
        p,p0:array[1..100] of longint;
        list:array[0..100000] of dword;
    procedure qsort(l,r:longint);
    var i,j,mid,t:longint;
    begin
      i:=l;j:=r;mid:=p[(l+r) div 2];
      repeat
        while p[i]<mid do inc(i);
        while p[j]>mid do dec(j);
        if i<=j then
          begin
            t:=p[i];p[i]:=p[j];p[j]:=t;
            inc(i);dec(j);
          end;
      until i>j;
      if i<r then qsort(i,r);
      if j>l then qsort(l,j);
    end;
    
    begin
      readln(k,n);
      for i:=1 to k do
        read(p[i]);
      qsort(1,k);
      list[1]:=1;
      for i:=2 to n+1 do
        begin
          t:=maxlongint;
          for j:=1 to k do
            begin
              while p[j]*list[p0[j]]<=list[i-1] do inc(p0[j]);
              if p[j]*list[p0[j]]<t then t:=p[j]*list[p0[j]];
            end;
          list[i]:=t;
        end;
      writeln(list[n+1]);
    end.
    丑数

    前两个失败的:

    program usaco_3;
    var k,n,i,j,t,t0:longint;
        p:array[1..100] of longint;
        list:array[1..100000] of longint;
    procedure qsort(l,r:longint);
    var i,j,mid,t:longint;
    begin
      i:=l;j:=r;mid:=p[(l+r) div 2];
      repeat
        while p[i]<mid do inc(i);
        while p[j]>mid do dec(j);
        if i<=j then
          begin
            t:=p[i];p[i]:=p[j];p[j]:=t;
            inc(i);dec(j);
          end;
      until i>j;
      if i<r then qsort(i,r);
      if j>l then qsort(l,j);
    end;
    
    function search(start,xi:longint):longint;
    var t,i:longint;
    begin
      for i:=1 to k do
        if start*p[i]>xi then
          begin
            t:=start*p[i];
            exit(t);
          end;
    end;
    
    begin
      readln(k,n);
      for i:=1 to k do
        read(p[i]);
      qsort(1,k);
      list[1]:=1;
      for i:=2 to n+1 do
        begin
          t:=maxlongint;
          for j:=1 to i-1 do
            begin
              t0:=search(list[j],list[i-1]);
              if t0<t then t:=t0;
            end;
          list[i]:=t;
        end;
      writeln(list[n+1]);
    end.
    丑数-demo1
    program usaco_3;
    var k,n,i,j,t,t0:longint;
        p:array[1..100] of longint;
        list,p0:array[1..100000] of longint;
    procedure qsort(l,r:longint);
    var i,j,mid,t:longint;
    begin
      i:=l;j:=r;mid:=p[(l+r) div 2];
      repeat
        while p[i]<mid do inc(i);
        while p[j]>mid do dec(j);
        if i<=j then
          begin
            t:=p[i];p[i]:=p[j];p[j]:=t;
            inc(i);dec(j);
          end;
      until i>j;
      if i<r then qsort(i,r);
      if j>l then qsort(l,j);
    end;
    
    function search(start,xi:longint):longint;
    var t,i:longint;
    begin
      if p0[start]>xi then exit(p0[start]);
      for i:=1 to k do
        if list[start]*p[i]>xi then
          begin
            t:=list[start]*p[i];
            p0[start]:=t;
            exit(t);
          end;
    end;
    
    begin
      readln(k,n);
      for i:=1 to k do
        read(p[i]);
      qsort(1,k);
      list[1]:=1;
      for i:=2 to n+1 do
        begin
          t:=maxlongint;
          for j:=1 to i-1 do
            begin
              t0:=search(j,list[i-1]);
              if t0<t then t:=t0;
            end;
          list[i]:=t;
        end;
      writeln(list[n+1]);
    end.
    丑数-demo2
  • 相关阅读:
    Spring Boot邮件功能
    jenkins自动部署
    spring boot定时任务解析
    类的加载classload和类对象的生成
    排序算法
    Robbin负载均衡
    ActiveMQ消息中间件
    hystrix熔断器
    css3整理--calc()
    css3整理--media
  • 原文地址:https://www.cnblogs.com/Sky-Grey/p/3514514.html
Copyright © 2011-2022 走看看