1. 程式人生 > >bzoj 3208: 花神的秒題計劃Ⅰ(Pu1 2018.10.1)

bzoj 3208: 花神的秒題計劃Ⅰ(Pu1 2018.10.1)

演算法:DFS,記憶化

難度:NOIP

題解:重點就是記憶化的部分,dfs的精髓,認真分析!

程式碼如下:

時間複雜度:O(n^2*m)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <cmath>
#include <algorithm>
#define ll long long
#define N 705
using namespace std;
int mapp[N][N];
int fla[N][N];
char str[5];
int dx[6]={0,0,1,-1};
int dy[6]={1,-1,0,0};
int f[N][N];
int n,m;
int dfs(int x,int y)
{
	if(fla[x][y]) return 0;
	if(f[x][y]) return f[x][y];
	f[x][y]=1;//!!!
	for(int i = 0;i <= 3;i++)
	{
		int xx=x+dx[i];
		int yy=y+dy[i];
		if(xx<=0||xx>n||yy<=0||yy>n) continue;//xx==0||yy==0,也是不符合的 
		if(mapp[xx][yy]>=mapp[x][y]) continue;//嚴格大於,,“=”也是不符合條件的! 
		f[x][y]=max(f[x][y],dfs(xx,yy)+1);/*注意,要加上此位置*/
	}
	return f[x][y];
}
int main()
{
	scanf("%d",&n);
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
		{
			scanf("%d",&mapp[i][j]);
		}
	}
	scanf("%d",&m);
	for(int i = 1;i <= m;i++)
	{
		int ans=0;
		scanf("%s",str+1);
		if(str[1]=='C')
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			mapp[a][b]=c;
		}else if(str[1]=='S')
		{
			int a,b,c,d;
			scanf("%d%d%d%d",&a,&b,&c,&d);
			for(int q = a;q <= c;q++)
			{
				for(int w = b;w <= d;w++)
				{
					fla[q][w]=1;
				}
			}
		}else if(str[1]=='B')
		{
			int a,b,c,d;
			scanf("%d%d%d%d",&a,&b,&c,&d);
			for(int q = a;q <= c;q++)
			{
				for(int w = b;w <= d;w++)
				{
					fla[q][w]=0;
				}
			}
		}else if(str[1]=='Q')
		{
			memset(f,0,sizeof(f));
			for(int s = 1;s <= n;s++)
			{
				for(int w = 1;w <= n;w++)
				{
					ans=max(ans,dfs(s,w));
				}
			}
			printf("%d\n",ans);
		}
	}
	return 0 ;
}