1. 程式人生 > 其它 >2021圖靈杯 E-nn與遊戲

2021圖靈杯 E-nn與遊戲

E.

E-nn與遊戲_第九屆“圖靈杯”NEUQ-ACM程式設計競賽個人賽 (nowcoder.com)

連結:https://ac.nowcoder.com/acm/contest/27302/E
來源:牛客網

先聊聊我對廣搜的認識:以一個點為中心往外擴散,每遇到一個可接受的點,把點的放進佇列,等到下一次使用,以此擴散至邊界。

記錄:用vis陣列記錄,傳值z+1表示步數,若成功則記錄並且點入佇列,不成功則放棄

關於[0,n) 真心覺得c中這個陣列定義下標從零開始真的是煩,有些題目又是從1開始,閉區間,開區間常常會搞錯,綜合考慮我還是接受從1開始的陣列,以後儘量在每一題中體現我的思想。

關於rep,由於我用了 rep和rrep來代替for,經常會被迷惑,還會在題目中巢狀使用,不小心就把i的範圍改了,重新迴圈的時候直接退出。

關於變數名稱的定義,這裡還需要斟酌,有的時候真的會迷惑!!!!!!

思路:

1.記錄:記錄障礙,記錄控制單位和敵對單位。

2.擴散:以控制單位為中心(記錄)x1y1,敵對中心為目標x2y2。

3.佇列: 以pair形式儲存,同時pair又存在map中來標記是否出現

3.函式:用於擴散和增加步數

4.輸出:vis [ x2 ] [ y2 ]-1。

對於步數的記錄:主函式解析,擴散函式中賦值

作用:每次都取上次的步數,防止出現重複計算,以及保證是最小值

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define endl '\n'
#define debug(x) cout<<"------"<<x<<"-----\n"
#define ok() cout<<"YES\n" 
#define gg() cout<<"NO\n"
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;--i)
#define IOS ios::sync_with_stdio(false),cin.tie(0);
typedef pair <int ,int >PII;
typedef vector <int > VI;
const int mod = 1e9+7;
const int INF =0x3f3f3f3f;
const int N=100010; 
using LL=long long;
queue<PII>qe;
map<PII,int>ma;
int x2,y2,n;
int vis[1005][1005]; 
int bari[1005][1005];
int p[11][5];
void ks(int x,int y,int z)
{
	//找著,且是第一次就找著 
	if(x==x2&&y==y2&&!vis[x][y])
	{
		vis[x][y]=z;
	}else if(x<1||x>n||y<1||y>n||vis[x][y]||bari[x][y]||ma.count({x,y}))
	//滿足邊界,正好踏到了其他點上,遇到了障礙 ,已經找過這個點
	{
		return;
	}else
	{
		vis[x][y]=z;
		qe.push({x,y});
	}
}
signed main()
{
	int m,t,x,y;
	cin>>n>>m;
	rep(i,1,m)
	{
		cin>>x>>y;
		x++;y++;
		bari[x][y]=-1;		//障礙 
	}
	
	cin>>t;
	rep(i,1,t)
	{
		rep(j,1,4)
		{
			cin>>p[i][j];
			p[i][j]++;
		}
		ma[{p[i][1],p[i][2]}]++;
		ma[{p[i][3],p[i][4]}]++;
	}
	
	rep(k,1,t)
	{
		rep(i,1,n)
		rep(j,1,n)
			vis[i][j]=0;
		
		x=p[k][1];y=p[k][2];x2=p[k][3];y2=p[k][4];
		while(!qe.empty()) qe.pop();
		qe.push({x,y});
		vis[x][y]=1;
		
		while(!qe.empty())
		{
			auto f=qe.front();
			x=f.fi;y=f.se;
			qe.pop();
			int z=vis[x][y];
			
			ks(x+1,y,z+1);
			ks(x-1,y,z+1);
			ks(x,y+1,z+1);
			ks(x,y-1,z+1);	
		}
		
		cout<<vis[x2][y2]-1<<endl;	
	}
}