blog正式转移到了这里:

http://blog.phoeagon.cz.cc



I know

phoeagon啲01世界

2009 年 1 月 2 日  星期五   晴天


Programming-简单基础题 分類: Programming Impossib...

 {謹供鄙視}
Treap版NOIP“明明的亂數”:
明明的亂數
明明想在學校中請一些同學一起做一項問卷調查,為了實驗的客觀性,他先用電腦生成了N個1到1000之間的隨機整數(N≤100),對於其中重複的數字,只保留一個,把其餘相同的數去掉,不同的數對應著不同的學生的學號。然後再把這些數從小到大排序,按照排好的順序去找同學做調查。請你協助明明完成“去重”與“排序”的工作。
輸入說明 :

每組輸入有2行,第1行為1個正整數,表示所生成的亂數的個數:N
第2行有N個用空格隔開的正整數,為所產生的亂數。
輸出說明 :

每組輸出也是2行,第1行為1個正整數M,表示不相同的亂數的個數。第2行為M個用空格隔開的正整數,為從小到大排好序的不相同的亂數。
範例輸入 :
10
20 40 32 67 40 20 89 300 400 15
範例輸出 :8
15 20 32 40 67 89 300 400
{TASK: 明明的亂數
ID: phoeagon
For: ***
LANG: PASCAL}
type
  node=^link;
  link=record
    num,p,yy:longint;
lc,rc:node;
  end;
var
   null,root:^link;
   n,count:longint; ou:boolean;
   function leftr(t:node):node;
     begin
    leftr:=t^.lc;
    t^.lc:=leftr^.rc;
    leftr^.rc:=t;
  end;
function rightr(t:node):node;
   begin
       rightr:=t^.rc;
    t^.rc:=rightr^.lc;
    rightr^.lc:=t;
   end;
   function insert(x:longint;t:node):node;
     begin
        if t=null then
       begin
                        new(t);t^.num:=x;
                        t^.p:=random(maxint);
                        t^.lc:=null;
   t^.rc:=null;
                        t^.yy:=1;
                        inc(count);
                     end
                     else if x=t^.num then
                       inc(t^.yy)
   else if x<t^.num then
     begin
        t^.lc:=insert(x,t^.lc);
      if t^.lc^.p<t^.p then
         t:=leftr(t);
     end
    else if x>t^.num then
      begin
           t^.rc:=insert(x,t^.rc);
     if t^.rc^.p<t^.p then
        t:=rightr(t);
      end;
   insert:=t;
  end;
   procedure search(x:node);
     begin
        if x=null then
       exit
   else begin
            search(x^.lc);
                          if not ou then begin
                             ou:=true;
        write(x^.num);
                             end
                             else write(' ',x^.num); 
                             //write(x^.num{,' ',x^.yy});
      search(x^.rc);
   end;
  end;
procedure work;
   var
     i,n,a:longint;  tmproot:node;
begin
       read(n);{new(tt);}
    {read(a);
    root:=insert(a,root);} //tmproot:=root;
    for i:=1 to n do
          begin
             read(a);
      root:=insert(a,root);
                                         //insert(a,null);
   end;
                        writeln(count);
  search(root);
end;
   begin
   randomize;  ou:=false;
   new(null);
   null^.p:=maxlongint;
   null^.lc:=null; null^.yy:=0;
   null^.rc:=null;
   root:=null;
   work;
   end.


離散化版“校門外的樹”(NOIP 2005)
內容 :
某校大門外長度為L的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1米。我們可以把馬路看成一個數軸,馬路的一端在數軸0的位置,另一端在L的位置;數軸上的每個整數點,即0,1,2,……,L,都種有一棵樹。
由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止點的座標都是整數,區域之間可能有重合的部分。現在要把這些區域中的樹(包括區域端點處的兩棵樹)移走。你的任務是計算將這些樹都移走後,馬路上還有多少棵樹。

輸入說明 :

每組輸入的第一行有兩個整數L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表馬路的長度,M代表區域的數目,L和M之間用一個空格隔開。接下來的M行每行包含兩個不同的整數,用一個空格隔開,表示一個區域的起始點和終止點的座標。
輸出說明 :

每組輸出包括一行,這一行只包含一個整數,表示馬路上剩餘的樹的數目。
範例輸入 :
500 3
150 300
100 200
470 471
範例輸出 :
298

{
Prob: 校門外的樹(Noip2005)
演算法:離散化
}
const
  maxm=110;
type
  node=record
    st,ed:longint;
//stn,edn:longint;
  end;
  link=record
    x:longint;
add:^longint;
end;
var
  d:array[0..2*maxm+2]of boolean;
  ct:array[0..2*maxm+2]of longint;
  pt:array[0..2*maxm]of node;
  tmp:array[0..2*maxm+2]of link;
  n,m,top:longint;
  procedure init;
    var
   i:longint;
begin
         read(n,m);top:=1;tmp[top].x:=0;{inc(top);tmp[top].x:=n;}
                tmp[m*2+2].x:=n;
   for i:=1 to m do
     begin
          read(pt.st,pt.ed);
       inc(top);tmp[top].x:=pt.st;tmp[top].add:[email protected];
       inc(top);tmp[top].x:=pt.ed;tmp[top].add:[email protected];
     end;
end;
  procedure qsort(l,r:longint);
    var
   i,j,x1:longint;
   y:link;
begin
      i:=random(r-l)+l;
   y:=tmp;tmp:=tmp[(l+r)div 2];tmp[(l+r)div 2]:=y;
   i:=l;j:=r;x1:=tmp[(l+r)div 2].x;
   repeat
          while (tmp.x<x1) do inc(i);
    while (tmp[j].x>x1) do dec(j);
    if not(i>j)then
      begin
           y:=tmp;tmp:=tmp[j];tmp[j]:=y;
        inc(i);dec(j);
      end;
   until i>=j;
   if i<r then qsort(i,r);
   if l<j then qsort(l,j);
end;
{procedure selectionsort(l,r:longint);
  var
    i,j,k:longint;t:link;
  begin
          for i:=l to r-1 do
      begin
          k:=i;
       for j:=i+1 to r do
         if (tmp[j].x<tmp[k].x)
                                     {or((tmp[j].x=tmp[k].x)and(tmp[j].add<tmp[k].add))}
                                     then
        k:=j;
      t:=tmp;tmp:=tmp[k];tmp[k]:=t;
   end;
  end;}
  procedure work;
      var
     i,j,count:longint;x1:^longint;
   begin
      count:=0;
      for i:=1 to top do
     ct:=tmp.x-tmp[i-1].x;
    for i:=2 to top do
      begin
        x1:=tmp.add;
     x1^:=i;
   end;
    for i:=1 to m do
      for j:=pt.st+1 to pt.ed do
      d[j]:=true;
     {for i:=1 to top do
      if not dthen
             inc(count,ct{-ct[i-1]});
              writeln(count); }
      for i:=1 to top do
      if dthen
                            if not d[i-1]then
        inc(count,ct+1)
                             else inc(count,ct);

    writeln(n+1-count);
   end;
   begin
            init;
     qsort(2,top);
     work;
   end.
 
 
校門外的樹(tree.pas/c/cpp)
某校大門外長度為L的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1米。我們可以把馬路看成一個數軸,馬路的一端在數軸0的位置,另一端在L的位置;數軸上的每個整數點,即0,1,2,……,L,都種有一棵樹。
由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止點的座標都是整數,區域之間可能有重合的部分。現在要把這些區域中的樹(包括區域端點處的兩棵樹)移走。你的任務是計算將這些樹都移走後,馬路上還有多少棵樹。
輸入說明 :

每組輸入的第一行有兩個整數L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表馬路的長度,M代表區域的數目,L和M之間用一個空格隔開。接下來的M行每行包含兩個不同的整數,用一個空格隔開,表示一個區域的起始點和終止點的座標。
輸出說明 :

每組輸出包括一行,這一行只包含一個整數,表示馬路上剩餘的樹的數目。
範例輸入 :
500 3
150 300
100 200
470 471
範例輸出 :
298
提示 :

對於20%的資料,區域之間沒有重合的部分;對於其他的資料,區域之間有重合的情況。
出處 :

NOIP2005 普及組

校門外的樹——Segment Tree版:
{
NOIP 校門外的樹
agorithm: simulation
data Structure: Segment_Tree (According to _gXX, point tree)
Many thanks to _gXX, who generously offered much assistance with the PKU 2777.
by: phoeagon
For y^3!
}
const
  lim=10000;
type
  node=record
    hd,ed,ct:longint;
f:boolean;
end;
var
   tree:array[0..2 shl 15]of node;
   n,m:longint;
  procedure build(a,b,nd:longint);
    begin
      tree[nd].hd:=a;tree[nd].ed:=b;tree[nd].ct:=0;tree[nd].f:=false;
   if a<b then
     begin
       build(a,(a+b)shr 1,nd*2);
    build((a+b)shr 1+1,b,nd*2+1);
     end; 
end;
  procedure del(a,b,nd:longint);
    var
   mid:longint;
begin
      if tree[nd].ct=tree[nd].ed-tree[nd].hd+1 then
     exit
    else if (a=tree[nd].hd)and(b=tree[nd].ed)then
      tree[nd].ct:=b-a+1
    else
      begin
         mid:=(tree[nd].hd+tree[nd].ed) shr 1;
      if b<=mid then
        del(a,b,nd*2)
      else if a>=mid+1 then
         del(a,b,nd*2+1)
      else
        begin
        del(a,mid,nd*2);
        del(mid+1,b,nd*2+1);
     end;
    tree[nd].ct:=tree[nd*2].ct+tree[nd*2+1].ct;
   end;
end;
  function calc(a,b,nd:longint):longint; //not actually needed, all the
                                         //queries are about the root node
     var
    mid:longint;
  begin
     if tree[nd].ct=0 then
    exit(0)
   else if tree[nd].ct=tree[nd].ed-tree[nd].hd+1 then
     exit(b-a+1)
   else if (tree[nd].hd=a)and
   (tree[nd].ed=b)then
     exit(tree[nd].ct)
    else begin
         mid:=(tree[nd].hd+tree[nd].ed)shr 1;
      if b<=mid then
        exit(calc(a,b,nd*2))
    else if a>mid then
      exit(calc(a,b,nd*2))
     else exit(calc(a,mid,nd*2)+calc(mid+1,b,nd*2+1));
    end;
  end;
procedure work;
   var
     i,a,b:longint;
   begin
        read(n,m);
     build(0,n,1);
     for i:=1 to m do
       begin
          read(a,b);
       del(a,b,1);
    end;
    //writeln(n+1-tree[1].ct);
    writeln(n+1-calc(0,n,1));
   end;
   begin
      work;
   end.
 
 






訪客留言 (返回 phoeagon 的日誌)

訪客名稱:
電郵地址: (不會公開)
驗證碼:  按此更新驗證碼 (如看不清楚驗證碼請點擊圖片刷新)
俏俏話: (必需 登入 後才能使用此功能)
[ 開啟多功能編輯器 ]







人氣:79383
暱稱: phoeagon
性別: 男
MORE...  
« May 2024 »
SMTWTFS
1234
567891011
12131415161718
19202122232425
262728293031
» 最新日誌
Blog Moved!
跨站jsMath实现
路由表是个好东西
Twitter Fav列表达陈100...
搞定了公式显示
» 日誌分類
全部 (175)
Code Storage (11)
Math&Phy@Chem@MM (8)
Music Anyway (5)
Programming Impossible (28)
RSS提示 (2)
StorageBox (5)
'Bout Here (12)
滑鼠人生 (42)
碎屑 (51)
未分類 (11)
» 訪客留言
最近三個月尚無任何留言
» 最近訪客
最近沒有訪客
» 每月文章
» 日誌訂閱
尚未訂閱任何日誌
» 我的好友
» 我的連結
Ink Mark --Jlim
StarKirby
|S||S||S|
「流年祭」
» 日誌統計
文章總數: 175
留言總數: 86
今日人氣: 153
累積人氣: 79383
» 站內搜索
RSS Feed