zoukankan      html  css  js  c++  java
  • 2020牛客寒假算法基础集训营5

    这两天玩的有点多。。。博客总结,鸽了好多。打比赛状态也差~

    先补个5的题解思路,晚点再补6.

    A.模板

    第一眼有点像编辑距离,但实际上编辑距离的dp似乎是对可以在任意位置修改的替换插入删除。

    然后深入想下,对于两个字符串前面部分的不同,你只能够通过替换去消去这个位置的差异,因为这里的插入和删除只针对尾部,然后遍历一遍,不同数加尾部的差值即可。

    B.牛牛战队的比赛地

    我也不知道哪来的绿色?三分答案的横坐标,或者二分答案。最大距离最小,经典二分题。

    我写的二分。

    对于一个给点的答案的距离,对每个点我们可以做个圆,求出与x轴交点,不断check更新这个x轴交点的l,r,最后一遍下来如果仍然满足,则这个答案是符合,然后往更小的即可。

    由于是浮点数,判定结束条件和l,r增减的时候都用eps,整体复杂度还是差不多的吧。

    C.C语言IDE

    大模拟,比赛居然还尝试写了,真的白费时间,赛后没补,哪天闲的蛋疼再来。

    D.牛牛与牛妹的约会

    我写的代码还特判两个同号还是异号的情况,好像不用也可。注意    k的立方根只能使的往靠0走更优,不能向外走更优。

    就比较当前这步是否      花1s走到当前位置的立方根,所缩小的和目标之间的距离与直接走1s是否更优。是就走,不是,说明往后再走,开k立方根没用了,直接加上与目标点距离即可。

    注意pow的底数不能是负数?特判搞一下即可。

    E.Enjoy the game

    博弈啊,就硬玩,发现当前轮到奇数状态必赢,取1就可。对于偶数的,就不能把奇数状态转移给别人,所以得拿偶数,然后这个偶数一旦存在奇数的因子,那么可以把这个偶数分成奇数份偶数,然后这样也是赢的。发现只有纯2的幂次才有。

    然后我用__builtin_popcount==1,就WA了,为啥,因为,这个是int范围的,要用__builtin_popcountll==1,学到了...

    然后还可以n&(n-1)==0 也是判2的幂次的trick

    F.碎碎念

    dp递推计数的题。。。我一直在想组合数的做法,还搞出来个公式 C(n+k-1,k-1),实际上复杂度爆炸。

    注意到每个长度序列都是由前面一些组合RJ和ac的序列形成的,数这样的组合,可以递推统计。主要是思维吧,想不太到。想到dp计数我估计就能做。

     1 #include <bits/stdc++.h>
     2 #ifndef ONLINE_JUDGE
     3 #define debug(x) cout << #x << ": " << x << endl
     4 #else
     5 #define debug(x)
     6 #endif
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=2e5+7;
    10 const int inf=0x3f3f3f3f;
    11 const int mod=1e9+7;
    12 
    13 ll dp[maxn][2];
    14 ll sum[maxn];
    15 int main()
    16 {
    17     ios::sync_with_stdio(false);
    18     cin.tie(0);
    19     int x;
    20     cin>>x;
    21     dp[0][0]=1;
    22     int mx=1e5;
    23     for(int i=1;i<=mx;++i)
    24     {
    25         dp[i][0]=(dp[i-1][1]+dp[i-1][0])%mod;
    26         if(i>=x) dp[i][1]=dp[i-x][0];
    27     }
    28     for(int i=1;i<=mx;++i)
    29         sum[i]=(sum[i-1]+dp[i][0]+dp[i][1])%mod;
    30     int q;
    31     cin>>q;
    32     while(q--)
    33     {
    34         int l,r;
    35         cin>>l>>r;
    36         ll res=sum[r]-sum[l-1];
    37         res=((res)%mod+mod)%mod;
    38         cout<<res<<'
    ';
    39     }
    40     return 0;
    41 }

    G.街机争霸

    bfs多一维带时间,感觉这方面还是挺弱的。僵尸的位置状态最多就1->k,k>-1,算上前进的方向,最多就2*(k-1)个状态,整个的僵尸移动就是时间对%2*(k-1)取模。mod=2*(k-1)

    后就按僵尸移动位置方向预处理僵尸每个时间会出现的位置,再防止重复开个vis[x][y][t%mod]。然后跟普通的迷宫bfs一样了。

    然后我这里地图数组mp必须得写在一个,涉及到数组内存分配问题?不然就段错误好难受啊。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 char mp[505][505];
     4 bool cor[505][505][30];
     5 bool vis[505][505][30];
     6 int dx[4]={-1,1,0,0};
     7 int dy[4]={0,0,-1,1};
     8 
     9 int mod;
    10 int n,m,p,k,sx,sy;
    11 struct node
    12 {
    13     int x,y,t;
    14 };
    15 queue<node>q;
    16 
    17 bool ok(int x,int y,int t)
    18 {
    19     return !cor[x][y][t%mod] && !vis[x][y][t%mod] && x>=0 && x<n && y>=0 && y<m && mp[x][y]!='&';
    20 }
    21 
    22 void bfs()
    23 {
    24     q.push({sx,sy,0});
    25     vis[sx][sy][0]=1;
    26     while(!q.empty())
    27     {
    28         node cur=q.front();q.pop();
    29         if(mp[cur.x][cur.y]=='A')
    30         {
    31             cout<<cur.t<<endl;
    32             return;
    33         }
    34         for(int i=0;i<4;++i)
    35         {
    36             int nx=cur.x+dx[i],ny=cur.y+dy[i],nt=cur.t+1;
    37             if(ok(nx,ny,nt))
    38             {
    39                 vis[nx][ny][nt%mod]=1;
    40                 q.push({nx,ny,nt});
    41             }
    42         }
    43     }
    44     cout<<"Oh no"<<endl;
    45     return ;
    46 }
    47 int main()
    48 {
    49     cin>>n>>m>>p>>k;
    50     mod=(k-1)*2;
    51     for(int i=0;i<n;++i)
    52     {
    53         cin>>mp[i];
    54         for(int j=0;j<m;++j)
    55             if(mp[i][j]=='L')
    56                 sx=i,sy=j;
    57     }
    58     while(p--)
    59     {
    60         int x,y;
    61         char op[10];
    62         cin>>x>>y>>op;
    63         x--;y--;
    64         cor[x][y][0]=1;
    65         int dir;
    66         if(op[0]=='U') dir=0;
    67         if(op[0]=='D') dir=1;
    68         if(op[0]=='L') dir=2;
    69         if(op[0]=='R') dir=3;
    70         for(int i=1; i<k; i++)
    71         {
    72             x+=dx[dir];y+=dy[dir];
    73             cor[x][y][i]=cor[x][y][mod-i]=1;
    74         }
    75     }
    76     bfs();
    77     return 0;
    78 }

    H.Hash

    看了几眼,发现26进制搞一下即可,莫名其妙的多组数据WA了我2发。算法竞赛不需要视力。

    就转化为26进制在加个mod,保证是最小,在转化回来即可。

    I.I题是个签到题  

    J.牛牛战队的秀场

    推下式子就能过了应该。

  • 相关阅读:
    倒车入库:场地模型线序
    Mini440之uboot移植之实践NAND启动(四)
    数据库mysql转为postgresql变动
    嵌入式Linux之vs code开发环境搭建
    Chrome Version 19.0.1055.1 dev Flash Missing plugin的修复
    再次解决,android 2.3运行凯立德问题
    笔记本双屏系统的组建
    gitfatal: unable to access : The requested URL returned error: 403
    C++ 学习拾遗 —— 点滴记录C++学习过程中遇到的问题以及整理
    linux 常用命令
  • 原文地址:https://www.cnblogs.com/Zzqf/p/12316427.html
Copyright © 2011-2022 走看看