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<<'\n';
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.牛牛战队的秀场

推下式子就能过了应该。

猜你喜欢

转载自www.cnblogs.com/Zzqf/p/12316427.html