Weather Forecast[POJ2044]

版权声明:作为一个蒟蒻,转载时请通知我这个蒟蒻 https://blog.csdn.net/zyszlb2003/article/details/89469565

欢迎大家访问我的老师的OJ———caioj.cn

题目描述

传送门

思路

这道题有点优秀。
先解释一下输入:
一行一行中给出了期间内的N天(不超过365天),接着是N行,给出了市场和节日的时间表。第i行给出了第i天的时间表。它由16个数字组成,0或1, 0表示正常的一天,1表示市场或节日。数字由一个或多个空格分隔。
比如说位置 ( x , y ) , 1 x , y 4 (x,y),1\le x,y\le4 ,则在输入中应该是在 ( x 1 ) 4 + y (x-1)*4+y 这个位置上。
我们采用二进制来表示,

for(int i=1;i<=n;i++)
		{
			for(int j=0;j<16;j++)
			{
				int w;scanf("%d",&w);
				(a[i]<<=1)|=w;
			}
		}

同时为了配套,我们需要在进行递归时,我们也要还原出这个二进制数。

inline int get(int x,int y)
{
	return 1<<(16-(x-1)*4-y);
}
int flag=get(x,y)|get(x,y+1)|get(x+1,y)|get(x+1,y+1);//2*2的云,以左上为坐标。
if(flag&a[day])return 0;//看看当前状态所处位置是否有节日。

因为题目说一个地区最多六天不下雨。
经过我慎重地思考(瞎模拟),得出:
只要四个角有过下雨,其他地区就一定有下过雨
所以我们要多开一个数组,记录四个角的状态。

struct node
{
	int d[5];
}st;

之后要记录是否来过这里或状态是否合法,以免浪费时间。
由于我太懒,所以我打了状态压缩。

bool pd(int day,int x,int y,node t)
{
	for(int i=1;i<=4;i++)if(t.d[i]>6)return 0;
	int flag=get(x,y)|get(x,y+1)|get(x+1,y)|get(x+1,y+1);
	if(flag&a[day])return 0;
	int s=t.d[4]+t.d[3]*8+t.d[2]*64+t.d[1]*512;
	if(v[day][(x-1)*3+y][s])return 0;
	return v[day][(x-1)*3+y][s]=1;
}

对了,根据题意,应该有九个状态方向。

const int dx[9]={0,1,-1,2,-2,0,0,0,0};
const int dy[9]={0,0,0,0,0,1,-1,2,-2};

AC code

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=370;
const int M=4100;
int n,a[N];
bool v[N][10][M];
const int dx[9]={0,1,-1,2,-2,0,0,0,0};
const int dy[9]={0,0,0,0,0,1,-1,2,-2};
struct node
{
	int d[5];
}st;
inline int get(int x,int y)
{
	return 1<<(16-(x-1)*4-y);
}
bool pd(int day,int x,int y,node t)
{
	for(int i=1;i<=4;i++)if(t.d[i]>6)return 0;
	int flag=get(x,y)|get(x,y+1)|get(x+1,y)|get(x+1,y+1);
	if(flag&a[day])return 0;
	int s=t.d[4]+t.d[3]*8+t.d[2]*64+t.d[1]*512;
	if(v[day][(x-1)*3+y][s])return 0;
	return v[day][(x-1)*3+y][s]=1;
}
bool dfs(int day,int x,int y,node t)
{
	if(day==n+1)return 1;
	if(!pd(day,x,y,t))return 0;
	for(int i=0;i<9;i++)
	{
		node nxt=t;
		for(int j=1;j<=4;j++)++nxt.d[j];
		int nx=x+dx[i],ny=y+dy[i];
		if(nx<1||nx>3||ny<1||ny>3)continue;
		if(nx==1)
		{
			if(ny==1)nxt.d[1]=0;
			else if(ny==3)nxt.d[2]=0;
		}
		else if(nx==3)
		{
			if(ny==1)nxt.d[3]=0;
			else if(ny==3)nxt.d[4]=0;
		}
		if(dfs(day+1,nx,ny,nxt))return 1;
	}
	return 0;
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		if(!n)break;
		memset(a,0,sizeof(a));
		memset(v,false,sizeof(v));
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<16;j++)
			{
				int w;scanf("%d",&w);
				(a[i]<<=1)|=w;
			}
		}
		for(int i=1;i<=4;i++)st.d[i]=1;
		puts(dfs(1,2,2,st)?"1":"0");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zyszlb2003/article/details/89469565
今日推荐