70pts 求助 & 关于O2
查看原帖
70pts 求助 & 关于O2
318004
yezl楼主2021/4/11 10:07

题目:P7473 [NOI Online 2021 入门组] 重力球

简介:在漫长的改代码时间之后,终于从几乎全T变成了 40pts\texttt{40pts}(其余的还是T)在开了O2以后终于 70pts\texttt{70pts} 了,不过上个同学和我代码的原理基本一样,也是 40pts\texttt{40pts} ,不过开O2后还是一样,就想问一下是为什么,顺便希望指导一下代码的改善方法,谢谢。

同学代码tie:DFS 40分求助

//我的代码
#include<bits/stdc++.h>
using namespace std;
const int N=255;
int n,m,q,x,y,a,b,c,d,ans=0x3f3f3f3f;
struct node{
	int k;//记录步数
	bool o;//标记障碍
}p[N][N][4];
void maps()//预处理,将每个格子可以往上下左右走的步数都记录下来
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			for(int k=0;k<n;k++)
			{
				int k0=i-p[i][j][0].k,k1=i+p[i][j][1].k,k2=j-p[i][j][2].k,k3=j+p[i][j][3].k;
				if(p[k0][j][0].o || p[k1][j][1].o || p[i][k2][2].o || p[i][k3][3].o) continue;
				if(!p[k0-1][j][0].o && k0-1>0)
					p[i][j][0].k++;
				if(!p[k1+1][j][1].o && k1+1<=n)
					p[i][j][1].k++;
				if(!p[i][k2-1][2].o && k2-1>0)
					p[i][j][2].k++;
				if(!p[i][k3+1][3].o && k3+1<=n)
					p[i][j][3].k++;
			}
		}
	}
}
void dfs(int a,int b,int c,int d,int cnt,int last)//dfs求答案
{
	int f=0;
	if(cnt>=ans || cnt>n || f==4) return ;
	if(a==c && b==d)
	{
		ans=min(ans,cnt);
		return ;
	}
	for(int i=0;i<=3;i++)
	{
		int k1=p[a][b][i].k,k2=p[c][d][i].k;
		if(k1==0 && k2==0)
		{
			f++;
			continue;
		}
		if(i==0 && last!=0)//上走,如果上一次是向下走就不向上了,下面同理 
			dfs(a-k1,b,c-k2,d,cnt+1,1);
		else if(i==1 && last!=1)//下走
			dfs(a+k1,b,c+k2,d,cnt+1,0);
		else if(i==2 && last!=2)//左走
			dfs(a,b-k1,c,d-k2,cnt+1,3);
		else if(i==3 && last!=3)//右走
			dfs(a,b+k1,c,d+k2,cnt+1,2);
	}
}
int main()
{
	scanf("%d %d %d",&n,&m,&q);
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&x,&y);
		for(int j=0;j<=3;j++) p[x][y][j].o=1;
	}
	maps();//预处理
	/*for(int o=0;o<=3;o++)//debug
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
				printf("%d ",p[i][j][o].k);
			printf("\n");
		}
		printf("\n\n");
	}*/
	while(q--)
	{
		scanf("%d %d %d %d",&a,&b,&c,&d);
		dfs(a,b,c,d,0,-1);
		if(ans==0x3f3f3f3f) printf("-1\n");
		else printf("%d\n",ans);
		ans=0x3f3f3f3f;
	}
	return 0;
}
2021/4/11 10:07
加载中...