多校冲刺 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。。。这位强者比我讲的更清楚

posted on 2021-11-01 16:00  JYFHYX  阅读(39)  评论(0编辑  收藏  举报