zoukankan      html  css  js  c++  java
  • 08-12 NOIP模拟测试18

    一次考得比一次烂了啊,考试状态也越来越差了啊。。。

    又要回到从前吗?。。。

    真的是大众分随便拿啊。。。

    那我就和大众一起退役吗?。。。

    一个T1大模拟明明想到简单的实现方法偏偏要bfs建图,然后建错了吧?呵。

    又是一个T1 90,又是细节,A题就那么难???

    T1 T2慌的不行,你在想什么啊。。。不,你的大脑已经死机了,你不会想了。。。  可时间不会等你。。。

    T2 dp打成shi,觉得暴搜减枝有戏,可你为什么不把它打完却草草了事啊,觉得拿不到100就不要了吗?。。。枝都不减等着TLE吧。

    脑子一团浆糊,自己和自己过不去,我就和强迫症卡死一辈子吧。。。

    T3 别说了,题都没看,白给的20分不要了。。。

    来到第一机房后,真心觉得这里的环境比隔壁好太多,原来那个不敢在大佬们面前出现的我,现在也会主动去问题。

    原来静不下心的我,现在一个人单人单桌,思考的更连续更深入了,挺好。

    像我这样嘈杂的人,在嘈杂的环境下会死掉吧。。。可我也不要破坏这氛围啊。

    所以,我才不要回去。。。

    才不要成为

    那个别人眼中的"noip大佬",

    那个"他们说自己是蒟蒻",

    那个什么两个月拿"省二",

    那个”暴力最强“。

    那个”没那水平还去小机房“。

    没关系,我还是说吧。

    其实我一直觉得,这是一种瞧不起。。。

    是我太敏感了?不过我还是要说

    这些字眼让我不爽,似乎一笔一画里都像是在说。。。“这个人没水平,不就是早学了吗?不就是运气好吗?文化课渣成那样,还没状态,我就看不起他”

    是,我之前自学过一点,我只会那几个关键字,可我什么算法都没入门。

    noip也就提前看了点搜索的概念,考场上靠yy分全是骗来的,我就是当时运气好。

    就像xxx说我不行一样,我觉得这些令我无法忍受。

    但别人这么做是有理由的,他们的想法是由于我的表现,是我现在太弱了,配不上这个曾经的巧合。

    是我之前太放纵自己了,给很多人都留下了不好的印象,给自己太多松懈的空间,抱歉,也是对自己,抱歉。。。

    我很讨厌别人看不起我,很害怕别人误解我,我很容易因为别人对我的看法而改变我的行动。

    也不能说以别人的意志为转移,但我好像曾经这样,于是我不想继续下去。。。

    我不能直接改变别人的想法,但我可以通过改变我的行动而间接影响别人的看法。

    于是这是我正在做的,而且,在很大程度上,是为了我,而不是他人。

    我想成为真正的有实力的人

    我想,这是我的一个进步吧。

    87天,来吧。


    少有的情绪波动。

    我什么时候这么玻璃了?

    下午踢球心情好了许多啊。

    让这不开心过去吧,只把教训留下。

    A. 引子

    说下我考场上不动脑子又不想重构的复杂方法。

    每次从bfs队列里拿出一个水箱卡住左右边界从上到下扫,扫到一个出发管就找到儿子水箱,建边并放到bfs队列里。

    这样能保证前向星扫出来就是深度递减的,对建完的图dfs后根遍历输出答案。

    所以实现起来十分复杂,当时明明想到简单方法但是大脑死机了。。。

    正解其实就是把那个bfs去掉也不用建图,直接dfs出答案。

    不过实现三个方向的移动函数,我觉得还是很帅的。

     1 bool left(int &x,int &y)
     2 {
     3     int ox=x,oy=y;
     4     do{
     5         if(z[x][y-1]=='.') break;
     6         --y;
     7     }while(z[x][y]!='+');
     8     return ox!=x||oy!=y;
     9 }
    10 bool right(int &x,int &y)
    11 {
    12     int ox=x,oy=y;
    13     do{
    14         if(z[x][y+1]=='.') break;
    15         ++y;
    16     }while(z[x][y]!='+');
    17     return ox!=x||oy!=y;
    18 }
    19 bool down(int &x,int &y)
    20 {
    21     do{
    22         if(z[x][y]=='-') return true;
    23         if(z[x+1][y]=='.') break;
    24         ++x;
    25     }while(z[x][y]!='+');
    26     return false;
    27 }

    前两个的返回值是 是否移动,down()返回是否遇到水箱顶部。

    因为是传引用和题目中左右+下移的组合移动方式。

    有以下骚操作:

    1 int find(int x,int y,int pre)
    2 {
    3     if(pre==1) left(x,y);
    4     else right(x,y);
    5     while(!down(x,y))
    6         if(!left(x,y)) right(x,y);
    7     return id[x+1][y];
    8 }

    find()用于实现从一个水箱出发找到儿子水箱,返回找到的水箱的离散编号。

      1 #include<cstdio>
      2 #include<queue>
      3 #include<algorithm>
      4 #define reg register
      5 #define F(i,a,b) for(register int (i)=(a);(i)<=(b);++(i))
      6 using namespace std;
      7 const int N=1025;
      8 const int inf=233333333;
      9 int read();
     10 char z[N][N];
     11 int n,m;
     12 int tx[5]={0,1,0,-1},ty[5]={1,0,-1,0},id[N][N];
     13 struct BK{
     14     int w,a,s,d,id;
     15     BK(){w=a=inf;}
     16 }bk[10086];
     17 int cnt=0;
     18 bool left(int &x,int &y)
     19 {
     20     int ox=x,oy=y;
     21     do{
     22         if(z[x][y-1]=='.') break;
     23         --y;
     24     }while(z[x][y]!='+');
     25     return ox!=x||oy!=y;
     26 }
     27 bool right(int &x,int &y)
     28 {
     29     int ox=x,oy=y;
     30     do{
     31         if(z[x][y+1]=='.') break;
     32         ++y;
     33     }while(z[x][y]!='+');
     34     return ox!=x||oy!=y;
     35 }
     36 bool down(int &x,int &y)
     37 {
     38     do{
     39         if(z[x][y]=='-') return true;
     40         if(z[x+1][y]=='.') break;
     41         ++x;
     42     }while(z[x][y]!='+');
     43     return false;
     44 }
     45 void bfs(int x,int y,int num)
     46 {
     47     queue<pair<int,int> > q;
     48     q.push(make_pair(x,y));
     49     id[x][y]=num;
     50     while(!q.empty())
     51     {
     52         x=q.front().first;
     53         y=q.front().second;
     54         q.pop();
     55         bk[num].w=min(bk[num].w,x-1);
     56         bk[num].s=max(bk[num].s,x+1);
     57         bk[num].a=min(bk[num].a,y-1);
     58         bk[num].d=max(bk[num].d,y+1);
     59         F(i,0,3)
     60         {
     61             int nx,ny;
     62             nx=x+tx[i];
     63             ny=y+ty[i];
     64             if(z[nx][ny]=='-'||z[nx][ny]=='|') continue;
     65             if(id[nx][ny]) continue;
     66             id[nx][ny]=num;
     67             q.push(make_pair(nx,ny));
     68         }
     69     }
     70 }
     71 int find(int x,int y,int pre)
     72 {
     73     if(pre==1) left(x,y);
     74     else right(x,y);
     75     while(!down(x,y))
     76         if(!left(x,y)) right(x,y);
     77     return id[x+1][y];
     78 }
     79 void dfs(int u)
     80 {
     81     for(reg int i=bk[u].s-1;i>=bk[u].w+1;--i)
     82     {
     83         if(z[i][bk[u].a-1]=='-') dfs(find(i,bk[u].a-1,1));
     84         if(z[i][bk[u].d+1]=='-') dfs(find(i,bk[u].d+1,2));
     85     }
     86     printf("%d
    ",bk[u].id);
     87 }
     88 int main()
     89 {
     90     scanf("%d %d",&n,&m);
     91     F(i,1,n) scanf("%s",z[i]+1);
     92     F(i,0,n+1) z[i][0]=z[i][m+1]='.';
     93     F(i,0,m+1) z[0][i]=z[n+1][i]='.';
     94     F(i,1,n)
     95     {
     96         F(j,1,m)
     97         {
     98             int oj=j,ttx=0;
     99             while(z[i][j]>='0'&&z[i][j]<='9')
    100             {
    101                 ttx=ttx*10+z[i][j]-48;
    102                 ++j;
    103             }
    104             if(ttx)
    105             {
    106                 bk[++cnt].id=ttx;
    107                 bfs(i,oj,cnt);
    108             }
    109         }
    110     }
    111     dfs(1);
    112     return 0;
    113 }
    View Code

    B. 可爱精灵宝贝

    这题暴搜+减枝玄学复杂度可A。

    说正解:区间dp。

    设dp[t][i][j][0/1]表示在t时刻[i,j]区间的左或右端点时的最大权值和。

    我们把区间离散化,实际让就是用m+1(起点建虚点)个精灵的相对位置作为端点的区间。

    然后从小区间转移过来就可以了。

    说下这样的正确性:

    如果我此时路过一个精灵点,它没消失我肯定是要拿的。

    所以区间内的我都有路过,即我能拿的都拿了,不可能再有贡献,也就不需要转移到小区间。

    每次能造成贡献的只有区间外的点,Tm^2的复杂度允许,我们可以每次只拿一个点。

    即设dp[t][i][j][0/1]从[l+1,r],[l,r-1]转移过来,分类讨论即可。

  • 相关阅读:
    store的应用
    创建简单的SimpleStore
    设置间隔一周的算法
    C#里缓存的使用
    javaFileWrite,FileReader
    javaArrayList
    java函数方法
    java学生管理系统(简易版)
    Tensorflow框架
    java日期
  • 原文地址:https://www.cnblogs.com/hzoi-yzh/p/11338956.html
Copyright © 2011-2022 走看看