持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
解题记录
B Hash
题目大意
对于一个字符串 ,定义其 Hash 函数为
环形字符串 仅包括 a,e,h,n 四种字母,且 。且长度不超过 200000。试将其划分成若干个连续子段 ,最大化 。
思路
易知一段连续子段的最大值不会超过 998244353,所以我们不会把连续子段划分的太长。
我们可以枚举第一个段的第一个元素将环展开,令 dp[i] 表示前 i 个字符能划分出的最大和,则转移方程为:
暴力跑出来最长子段的长度不会超过15。题解给出了证明:
代码
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
char a[200021];
long long w[200021],dp[200021],d[21],ans;
int n;
int main()
{
cin>>a+1;
n=strlen(a+1);
for (int i=1;i<=n;i++)
if (a[i]=='a') w[i]=1;
else if (a[i]=='e') w[i]=2;
else if (a[i]=='h') w[i]=3;
else if (a[i]=='n') w[i]=4;
for (int l=1,r;l<=16;++l)
{
r=l+n-1;
w[r+1]=w[l];
memset(d,0,sizeof(d));
memset(dp,0,sizeof(dp));
for (int i=l;i<=r;i++)
for (int j=16;j>=1;--j)
{
d[j]=(d[j-1]*31+w[i])%998244353;
if (i-j>=0) dp[i]=max(dp[i],dp[i-j]+d[j]);
}
ans=max(ans,dp[r]);
}
printf("%lld",ans);
return 0;
}
I Oshwiciqwq 的电梯
题目大意
有一个长方体大楼,长 n 个 单位,宽 m 个单位,高 h 个单位。这个大楼里每个长宽高各为 1 个单位的空间是一个房间,可以用三维坐标 来表示,其中 。
大楼有 k 个电梯,每个电梯是朝坐标增大的方向环线运行的,在坐标最大处可以运行一次.瞬移到坐标最小处。不同电梯的运行轨道不相交。 保证了每两个房间之间都是间接可达的。所有电梯运行一个单位的时间为 1 秒,容量为无穷大。
每个电梯初始所在位置不同,第 i 个电梯 0 秒时在坐标为 的房间。电梯只能在整秒时刻开始移动或者结束移动,并且在电梯到达某房间后,乘客会在到达的同一时刻瞬移进出电梯门。
有 q 个乘客,第 i 个乘客在 秒到达,想要从位于 的房间到达位于 的房间。
规定乘客的路线为: ,即按顺序先后乘坐平行 x 轴,y 轴与 z 轴的电梯。如果某个阶段无需乘坐电梯已经到达,则直接忽略。在乘客进行某个阶段的移动时,只会搭乘对应方向的电梯。 具体运行策略如下:
- 电梯一开始在给定的坐标,方向为平行于对应坐标轴的正方向,一直环线运行
- 每到达一个房间,所有到达当前阶段目的地的乘客会按编号从小到大下电梯。然后在这个房间的乘 客会按编号从小到大上电梯。一个乘客下电梯之后,如果还没有到达最终目的地,那么会在原地等待下一个电梯,换乘至少需要一秒的时间。在出电梯的下一秒才能进入另一个电梯。
- 同一时刻编号小的电梯的所有进出事件发生在编号大的电梯前。
输出乘客上下电梯的信息。
思路
模拟,数据范围很小不会TLE。
我使用了结构体来简便代码的编写。
代码
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
int wall[3],k,q;
struct cell{
int x[3];
void get()
{
scanf("%d%d%d",&x[0],&x[1],&x[2]);
}
bool operator != (const cell c) const
{
if (x[0]!=c.x[0]) return 1;
if (x[1]!=c.x[1]) return 1;
if (x[2]!=c.x[2]) return 1;
return 0;
}
};
struct ele{
cell cl;
int type;
void nxt()
{
cl.x[type]++;
if (cl.x[type]>wall[type]) cl.x[type]=1;
}
}e[301];
struct people{
cell cl,to;
int t,flg,eleid;
int geteltype()
{
if (cl.x[0]!=to.x[0]) return 0;
if (cl.x[1]!=to.x[1]) return 1;
if (cl.x[2]!=to.x[2]) return 2;
return 3;
}
}p[51];
int allpeoplearriveddestination()
{
for (int i=1;i<=q;++i)
if (p[i].geteltype()!=3) return 0;
return 1;
}
//priority_queue<int> peopleid[301];
int main()
{
scanf("%d%d%d",&wall[0],&wall[1],&wall[2]);
int T=0;
scanf("%d",&k);
for (int i=1;i<=k;++i)
{
scanf("%d",&e[i].type);
e[i].cl.get();
}
scanf("%d",&q);
for (int i=1;i<=q;++i)
{
scanf("%d",&p[i].t);
p[i].cl.get();
p[i].to.get();
}
while (1)
{
T++;
if (allpeoplearriveddestination()) return 0;
for (int i=1;i<=k;++i)
{
e[i].nxt();
for (int j=1;j<=q;++j)
{
if (p[j].eleid!=i) continue;
p[j].cl=e[i].cl;
if (p[j].geteltype()==e[i].type) continue;
p[j].flg=1;
p[j].eleid=0;
printf("[%ds] Person %d OUT Elevator %d at (%d, %d, %d)\n",T,j,i,e[i].cl.x[0],e[i].cl.x[1],e[i].cl.x[2]);
}
for (int j=1;j<=q;++j)
{
if (p[j].flg) continue;
if (p[j].t>T) continue;
if (p[j].cl!=e[i].cl) continue;
if (p[j].geteltype()!=e[i].type) continue;
if (p[j].eleid!=0) continue;
p[j].eleid=i;
printf("[%ds] Person %d IN Elevator %d at (%d, %d, %d)\n",T,j,i,e[i].cl.x[0],e[i].cl.x[1],e[i].cl.x[2]);
}
}
for (int j=1;j<=q;++j) p[j].flg=0;
}
}