NOIP2011解题报告-Day1

题目:

https://files.cnblogs.com/lijianlin1995/NOIP2011%E6%8F%90%E9%AB%98%E7%BB%84Day1.pdf

        CLJ神犇的NOIP题解应该是最广为流的,但是神犇就是神犇,追求复杂度,方法很高端。所以我写一点能过就行的算法。RQNOJ提交通过了。

铺地毯

        第一感觉二维线段树,发现只查询一个点,可以朴素。如果halt要注意文件操作。

View Code
 1 type Tdt=record
 2       x,y,xl,yl:longint;
 3       end;
 4 var dt:array[1..10000] of Tdt;
 5     i,color,n,x,y:longint;
 6 begin
 7   readln(n);
 8   for i:=1 to n do
 9     with dt[i] do
10       readln(x,y,xl,yl);
11   readln(x,y);
12   color:=-1;
13   for i:=n downto 1 do
14     if (x>=dt[i].x)and(x<=dt[i].x+dt[i].xl)and
15        (y>=dt[i].y)and(y<=dt[i].y+dt[i].yl)
16          then begin
17               color:=i;
18               break;
19               end;
20   writeln(color);
21 end.

旅馆

        考试的时候写的O(n^2)的算法,枚举左右端点,维护区间最小值,得分很低。

把两个人的住宿位置看做一个闭区间的左右端点。一个合法的区间要求:

        I:含有一个点i满足ok[i]=1

        II:color[l]=color[r]

        求出合法的区间数即为答案。

        维护前缀和,count[i][j]为前1..i颜色j的数量,用指针f记录最后出现ok[i]=1的i。如果一个区间可以由靠左的ok[i]满足,一定可以由区间内靠右的ok[i]满足,不妨让最靠右的ok[i]满足。从1到n枚举区间右端点。通过前缀和计算左端点的方案数。

1.ok[i]=1 可以在i喝咖啡,右边的人可以住的位置是count[i-1][color[i]],f更改为i;(条件I被右端点满足)

2.ok[i]=0 在f喝咖啡,inc(ans,count[f][color[i]]);(条件II被f满足)

View Code
 1 program hotel;
 2 const maxn=200000;
 3 var color:array[0..maxn] of byte;
 4     ok:array[0..maxn] of boolean;
 5     n,p,k,i,f,t:longint;
 6     count:array[0..maxn,0..50] of longint;
 7     ans:int64=0;
 8 begin
 9 fillchar(count,sizeof(count),0);
10 readln(n,k,p);f:=0;
11 for i:=1 to n do
12   begin
13   readln(color[i],t);
14   if t<=p then ok[i]:=true
15           else ok[i]:=false;
16   count[i]:=count[i-1];
17   inc(count[i][color[i]]);
18   end;
19 for i:=1 to n do
20   begin
21   if ok[i] then f:=i-1;
22   inc(ans,count[f][color[i]]);
23   if ok[i] then inc(f);
24   end;
25 writeln(ans);
26 end.

 

Mayan游戏

        DFS,复杂度5*7^5=52521875不大,加上下落和清除,期望得分30—100。要注意横纵坐标和行列的关系。几个剪枝和要注意的问题:

1.如果一个方块左边有方块,那左边的方块右移比右边的方块左移优。
2.方块移动以后没有处理下落会WA40
3.读数据出问题,如果一行有7个方块,会有8个数字(最后一个是0),WA20
4.处理消除后的方块下落时下标越界。
5.忘记向左移动 WA60
        2的处理写疵了,索性用了消除后的下落过程。

        考试跟KAC大神同考场,考完大神叹息“我写了3KB”

View Code
  1 program mayan;
  2 TYPE Tmap=array[0..4,0..7] of shortint;
  3 var n,i,j,step:longint;
  4     a:Tmap;
  5     t:shortint;
  6     x,y,g:array[1..5] of integer;
  7 procedure swap(var a,b:shortint);
  8 var t:shortint;begin t:=a;a:=b;b:=t;end;
  9 procedure print;
 10           var i:longint;
 11           begin
 12           for i:=1 to step do
 13             writeln(x[i],' ',y[i],' ',g[i]);
 14           halt;
 15           end;
 16 function  clean(var map:Tmap):boolean;
 17           var i,j,k:integer;
 18               finish:boolean;
 19               f:array[0..4,0..6] of boolean;
 20           begin
 21           clean:=true;
 22           fillchar(f,sizeof(f),false);
 23           for i:=0 to 4 do
 24             for j:=0 to 6 do
 25               if map[i][j]<>0 then
 26                 begin
 27                 if(i in [1..3])and
 28                   (map[i][j]=map[i-1][j])and
 29                   (map[i][j]=map[i+1][j])
 30                   then begin
 31                        f[i][j]:=true;
 32                        f[i-1][j]:=true;
 33                        f[i+1][j]:=true;
 34                        end;
 35                 if(j in [1..5])and
 36                   (map[i][j]=map[i][j+1])and
 37                   (map[i][j]=map[i][j-1])
 38                   then begin
 39                        f[i][j]:=true;
 40                        f[i][j+1]:=true;
 41                        f[i][j-1]:=true;
 42                        end;
 43                 end;
 44           for i:=0 to 4 do
 45             for j:=6 downto 0 do
 46               if f[i][j] then
 47                 begin
 48                 clean:=false;
 49                 map[i][j]:=0;
 50                 end;
 51           end;
 52 procedure fall(var map:Tmap);
 53           var i,j,k:integer;
 54           begin
 55           for i:=0 to 4 do
 56             for j:=1 to 6 do
 57               if(map[i][j]<>0)and(map[i][j-1]=0)
 58                 then begin
 59                      k:=j;
 60                      while(k>0)and(map[i][k-1]=0)do dec(k);
 61                      map[i][k]:=map[i][j];map[i][j]:=0;
 62                      end;
 63           end;
 64 function  finish(map:Tmap):boolean;
 65           var i,j:longint;
 66           begin
 67           for i:=0 to 4 do
 68             for j:=0 to 6 do
 69               if map[i][j]<>0
 70                 then exit(false);
 71           exit(true);
 72           end;
 73 procedure DFS(map:Tmap);
 74           var i,j,k:integer;
 75           begin
 76           if step<>0 then swap(map[x[step]][y[step]],map[x[step]+g[step]][y[step]]);
 77           repeat fall(map) until clean(map);
 78           if step=n then if finish(map)then print
 79                                        else exit;
 80           for i:=0 to 4 do
 81             for j:=0 to 6 do
 82               begin
 83               if map[i][j]<>0
 84                 then begin
 85                      inc(step);
 86                      if(i>0)and(map[i-1][j]=0)
 87                        then begin
 88                             x[step]:=i;
 89                             y[step]:=j;
 90                             g[step]:=-1;
 91                             DFS(map);
 92                             end;
 93                      if(i<4)
 94                        then begin
 95                             x[step]:=i;
 96                             y[step]:=j;
 97                             g[step]:=1;
 98                             DFS(map);
 99                             end;
100                      dec(step);
101                      end;
102               end;
103           end;
104 begin
105 readln(n);step:=0;
106 for i:=0 to 4 do
107   begin
108   t:=-1;
109   repeat
110     inc(t);
111     read(a[i][t]);
112   until a[i][t]=0;
113   end;
114 DFS(a);
115 writeln('-1');
116 end.
posted @ 2012-08-12 13:06  ljlin  阅读(1533)  评论(0编辑  收藏  举报