多校冲刺 NOIP 20211029 模拟 (19)
T1 特殊字符串
大水题一个,dp[i]为以i结尾的最优情况是多少,枚举下一个字符是什么转移就行了
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int maxn=1e5+5;
char s[maxn];int n,m;
int dp[maxn],a[maxn];
vector<int>vec[27];
int tong[maxn][27],val[27][27];
signed main()
{
freopen("shiki.in","r",stdin);
freopen("shiki.out","w",stdout);
n=read();scanf("%s",s+1);
for(int i=1;i<=n;i++)
{
a[i]=s[i]-'a'+1;
vec[a[i]].push_back(i);
tong[i][a[i]]++;
for(int j=1;j<=26;j++)
tong[i][j]+=tong[i-1][j];
}
m=read();
for(int i=1;i<=m;i++)
{
char x,y;int z;cin>>x>>y>>z;
val[x-'a'+1][y-'a'+1]+=z;
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,dp[i]);
for(int j=1;j<=26;j++) if(tong[i][j]!=tong[n][j])
dp[vec[j][tong[i][j]]]=max(dp[vec[j][tong[i][j]]],dp[i]+val[a[i]][j]);
}
cout<<ans<<endl;
}
T2 宝可梦
我是沙比,想到正解却觉得自己实现不了结果没有打,暴力还错了。。。。。
我们发现题目里告诉我们每两个点有且仅有1条道路,也就是说每个方块连起来其实是一棵树,每个点最多连接4条边
那么我们可以建立出这课树的欧拉序,记录每个点向四个方向走的时间戳,以及从四个方向到它的时间戳,然后就可以统计答案了
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int maxn=5e5+5;
vector<bool>vec[maxn];
int dis[maxn][5],ed[maxn][5],n,m,cnt;char s[maxn];
inline int id(int x,int y){return (x-1)*m+y;}
inline int sb(char c)
{
if(c=='U')return 1;
if(c=='D')return 2;
if(c=='L')return 3;
if(c=='R')return 4;
return 5;
}
inline void bfs(int x,int y)//1上,2下,3左,4右
{
int goal=1;
while(1)
{
if(goal==1)
{
if(!vec[x][y+1]&&!dis[id(x,y)][4]){dis[id(x,y)][4]=ed[id(x,y+1)][4]=++cnt;y++;goal=4;}
else if(!vec[x-1][y]&&!dis[id(x,y)][1]){dis[id(x,y)][1]=ed[id(x-1,y)][1]=++cnt;x--;goal=1;}
else if(!vec[x][y-1]&&!dis[id(x,y)][3]){dis[id(x,y)][3]=ed[id(x,y-1)][3]=++cnt;y--;goal=3;}
else if(!vec[x+1][y]&&!dis[id(x,y)][2]){dis[id(x,y)][2]=ed[id(x+1,y)][2]=++cnt;x++;goal=2;}
else break;
}
else if(goal==2)
{
if(!vec[x][y-1]&&!dis[id(x,y)][3]){dis[id(x,y)][3]=ed[id(x,y-1)][3]=++cnt;y--;goal=3;}
else if(!vec[x+1][y]&&!dis[id(x,y)][2]){dis[id(x,y)][2]=ed[id(x+1,y)][2]=++cnt;x++;goal=2;}
else if(!vec[x][y+1]&&!dis[id(x,y)][4]){dis[id(x,y)][4]=ed[id(x,y+1)][4]=++cnt;y++;goal=4;}
else if(!vec[x-1][y]&&!dis[id(x,y)][1]){dis[id(x,y)][1]=ed[id(x-1,y)][1]=++cnt;x--;goal=1;}
else break;
}
else if(goal==3)
{
if(!vec[x-1][y]&&!dis[id(x,y)][1]){dis[id(x,y)][1]=ed[id(x-1,y)][1]=++cnt;x--;goal=1;}
else if(!vec[x][y-1]&&!dis[id(x,y)][3]){dis[id(x,y)][3]=ed[id(x,y-1)][3]=++cnt;y--;goal=3;}
else if(!vec[x+1][y]&&!dis[id(x,y)][2]){dis[id(x,y)][2]=ed[id(x+1,y)][2]=++cnt;x++;goal=2;}
else if(!vec[x][y+1]&&!dis[id(x,y)][4]){dis[id(x,y)][4]=ed[id(x,y+1)][4]=++cnt;y++;goal=4;}
else break;
}
else if(goal==4)
{
if(!vec[x+1][y]&&!dis[id(x,y)][2]){dis[id(x,y)][2]=ed[id(x+1,y)][2]=++cnt;x++;goal=2;}
else if(!vec[x][y+1]&&!dis[id(x,y)][4]){dis[id(x,y)][4]=ed[id(x,y+1)][4]=++cnt;y++;goal=4;}
else if(!vec[x-1][y]&&!dis[id(x,y)][1]){dis[id(x,y)][1]=ed[id(x-1,y)][1]=++cnt;x--;goal=1;}
else if(!vec[x][y-1]&&!dis[id(x,y)][3]){dis[id(x,y)][3]=ed[id(x,y-1)][3]=++cnt;y--;goal=3;}
else break;
}
}
}
inline int getdis(int p1,int p2,int p3,int p4,int goal)
{
if(p1==p3&&p2==p4)return 0;
int ans=123456789;
int tmp=dis[id(p1,p2)][goal];
if(ed[id(p3,p4)][1])
if(ed[id(p3,p4)][1]>=tmp) ans=min(ans,ed[id(p3,p4)][1]-tmp+1);
else ans=min(ans,cnt-tmp+ed[id(p3,p4)][1]+1);
if(ed[id(p3,p4)][2])
if(ed[id(p3,p4)][2]>=tmp) ans=min(ans,ed[id(p3,p4)][2]-tmp+1);
else ans=min(ans,cnt-tmp+ed[id(p3,p4)][2]+1);
if(ed[id(p3,p4)][3])
if(ed[id(p3,p4)][3]>=tmp) ans=min(ans,ed[id(p3,p4)][3]-tmp+1);
else ans=min(ans,cnt-tmp+ed[id(p3,p4)][3]+1);
if(ed[id(p3,p4)][4])
if(ed[id(p3,p4)][4]>=tmp) ans=min(ans,ed[id(p3,p4)][4]-tmp+1);
else ans=min(ans,cnt-tmp+ed[id(p3,p4)][4]+1);
return ans;
}
signed main()
{
freopen("pokemon.in","r",stdin);
freopen("pokemon.out","w",stdout);
n=read();m=read();
for(int i=1;i<=n;i++)
{
scanf("%s",s+1); vec[i].push_back(1);
for(int j=1;j<=m;j++) if(s[j]=='X')
vec[i].push_back(1); else vec[i].push_back(0);
vec[i].push_back(1);
}
for(int i=1;i<=m+2;i++)
vec[0].push_back(1),vec[n+1].push_back(1);
bool flag=0;int q=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!(vec[i][j])&!flag)
{bfs(i,j);flag=1;break;}
while(q--)
{
int p1=read(),p2=read(),p3=read(),p4=read();
char c; cin>>c;printf("%d\n",getdis(p1,p2,p3,p4,sb(c)));
}
}
T3 矩阵
一个sb题目,然后答案没跟1取max爆蛋了,日了狗了。。。。
一个记忆化搜索,复杂度\(O(nm)\)
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int maxn=4e5+6;
vector<int>vec[maxn];
int a[maxn],n,m,dep[maxn],que[maxn],top;
vector<pii>tor[maxn];
inline int id(int x,int y){return (x-1)*m+y;}
inline pii zh(int x){return mp((x-1)/m+1,((x-1)%m)+1);}
inline int dfs(int x,int y,int bs)
{
if(dep[id(x,y)]) return dep[id(x,y)];
que[++top]=id(x,y); dep[id(x,y)]=1;int sum=0;
int tmp1=vec[x-1][y],tmp2=vec[x][y-1],tmp3=vec[x+1][y],tmp4=vec[x][y+1];
if(x!=0&&!(tmp1%vec[x][y])&&tmp1/vec[x][y]==bs){dfs(x-1,y,bs);sum=max(sum,dep[id(x-1,y)]);}
if(y!=0&&!(tmp2%vec[x][y])&&tmp2/vec[x][y]==bs){dfs(x,y-1,bs);sum=max(sum,dep[id(x,y-1)]);}
if(x!=n&&!(tmp3%vec[x][y])&&tmp3/vec[x][y]==bs){dfs(x+1,y,bs);sum=max(sum,dep[id(x+1,y)]);}
if(y!=m&&!(tmp4%vec[x][y])&&tmp4/vec[x][y]==bs){dfs(x,y+1,bs);sum=max(sum,dep[id(x,y+1)]);}
dep[id(x,y)]+=sum;return dep[id(x,y)];
}
signed main()
{
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
n=read();m=read();
for(int i=1;i<=n;i++)
{
vec[i].push_back(40001);
for(int j=1;j<=m;j++)
vec[i].push_back(read());
vec[i].push_back(40001);
}
for(int i=1;i<=m+2;i++)
{
vec[n+1].push_back(40001);
vec[0].push_back(40001);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(vec[i][j]==vec[i-1][j]){puts("-1");return 0;}
if(vec[i][j]==vec[i][j-1]){puts("-1");return 0;}
if(vec[i][j]==vec[i+1][j]){puts("-1");return 0;}
if(vec[i][j]==vec[i][j+1]){puts("-1");return 0;}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int tmp1=vec[i-1][j],tmp2=vec[i][j-1],tmp3=vec[i+1][j],tmp4=vec[i][j+1];
if(i!=0&&(!(tmp1%vec[i][j])))
{
int tmp=tmp1/vec[i][j];
tor[tmp].push_back(mp(i,j));
}
if(j!=0&&(!(tmp2%vec[i][j])))
{
int tmp=tmp2/vec[i][j];
tor[tmp].push_back(mp(i,j));
}
if(i!=n&&(!(tmp3%vec[i][j])))
{
int tmp=tmp3/vec[i][j];
tor[tmp].push_back(mp(i,j));
}
if(j!=m&&(!(tmp4%vec[i][j])))
{
int tmp=tmp4/vec[i][j];
tor[tmp].push_back(mp(i,j));
}
}
}
int ans=0;
for(int i=2;i<=40000;i++)
{
for(int j=1;j<=top;j++)dep[que[j]]=1;top=0;
for(auto y:tor[i]) {ans=max(ans,dfs(y.fi,y.se,i));}
}
printf("%d\n",max(ans,1));
}
T4 乘法
emmm。。。这位强者比我讲的更清楚