墙角数枝梅,凌寒独自开。

遥知不是雪,为有暗香来。——王安石

题目:天气预报

网址:http://poj.org/problem?id=2044

你是一个可以控制降雨的神仙。

你是一个仁慈的神,希望土地在平时可以有足够的雨水,在赶集和过节能够充满阳光。

你负责掌控一个村子的天气状况。

这个村子呈4 x 4的网格状分布,村子内的每个区域被编号如下图所示:

你拥有一片2 x 2大小的云,这片云不能到村子以外的地方。

你将获得一段时间内村子每个区域的赶集和过节时间表。

在这段时间的第一天,中部地区(6-7-10-11)将会下雨。

在接下来的每一天中,您可以在四个基本方向(东南西北)之中选取一个方向,将云移动1或2个方格,或将其保持在相同位置。

不允许对角线移动。

任何地区都不能连续七天或以上时间都不降雨。

这段时间以外的日子的下雨状况你无需做任何考虑。

输入格式

输入包含多组测试用例。

对于每组测试用例,第一行包含一个整数N,表示这段时间的具体天数。

接下里N行,描绘了接下来N天的赶集和过节时间表,第i行表示第i天的时间表。

这N行里,每行包含16个数字(0或1),0表示正常的一天,1表示赶集和过节的一天,第i个数字表示第i个区域的具体情况。

每行数字之间用空格隔开。

当输入测试用例N=0时,表示输入终止,且该用例无需处理。

输出格式

每个测试用例输出一个整数0或1,如果可以保证整个时间段内,该下雨的地方下雨,不该下的地方不下,则输出1。

如果不能保证则输出0,每个结果占一行。

数据范围

1≤N≤365

输入样例:
1
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
7
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 1 0 0 0 0 1 1 0 0 1
0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0
0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0
7
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0
0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0
1 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0
0
输出样例:
0
1
0
1

这道题其实细节上颇多。

首先,判断每个地区是否连续七天没有浇水,实际上可以通过四个角来判断;

如果定义状态为该云目前的坐标,那么,当四个角中其中有不符题意的状态,难以表示;

如果该状态为坐标以及四个角的情况,那么,对于相同状态下,不同天数所处的情况也不同;

综上,定义:状态(time,(x,y),(d1,d2,d3,d4));

因此,对于这样一个状态,是满足唯一性,也就是说,可以保证该状态可以准确描述状态的情况;

连续七天,因此为了保险起见,我们使用八进制状态压缩(d1,d2,d3,d4),即d1 + d2 * 8 + d3 * 64 + d4 * 512;

其余,就注意细节即可;

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
struct state
{
int turn, pos, code;
state (int x, int y, int z) : turn(x), pos(y), code(z) {}
};
const int dx[10] = {-1, 1, 0, 0, -2, 2, 0, 0}, dy[10] = {0, 0, -1, 1, 0, 0, -2, 2};
bool day[366][17], vis[366][17][4096];
int n;
bool valid(state p)
{
if(vis[p.turn][p.pos][p.code]) return false;
for(int i = 0; i < 4; ++ i)
{
if(p.code % 8 >= 7) return false;
p.code >>= 3;
}
if(day[p.turn][p.pos] || day[p.turn][p.pos + 1] || day[p.turn][p.pos + 4] || day[p.turn][p.pos + 5]) return false;
return true;
}
bool valid(int x, int y)
{
if(x < 0 || x > 2 || y < 0 || y > 2) return false;
//be aware of it : The range is [0, 2] !!
return true;
}
bool bfs()
{
queue <state> Q;
int x, y;
int p[4] = {}, tmp = 0;
while(!Q.empty()) Q.pop();
memset(vis, false, sizeof(vis));
if(!valid(state(1, 6, 1 + 8 + 64 + 512))) return false;
vis[1][6][1 + 8 + 64 + 512] = true;
Q.push(state(1, 6, 1 + 8 + 64 + 512));
// The coodinate must be transfered into this form (x,y) to avoid mistakes about position!!
while(!Q.empty())
{
state now = Q.front(); Q.pop();
tmp = now.code;
for(int i = 0; i < 4; ++ i)
{
p[i] = tmp % 8;
tmp >>= 3;
}
x = (now.pos - 1) / 4, y = (now.pos - 1) % 4;
for(int i = 0; i < 9; ++ i)
{
state next = state(now.turn + 1, (x + dx[i]) * 4 + y + 1 + dy[i], 0);
if(!valid(x + dx[i], y + dy[i])) continue; switch(next.pos)
{
case 1:
{
next.code = (p[1] + 1) * 8 + (p[2] + 1) * 64 + (1 + p[3]) * 512;
break;
}
case 3:
{
next.code = p[0] + 1 + (p[2] + 1) * 64 + (1 + p[3]) * 512;
break;
}
case 9:
{
next.code = p[0] + 1 + (p[1] + 1) * 8 + (1 + p[3]) * 512;
break;
}
case 11:
{
next.code = p[0] + 1 + (p[1] + 1) * 8 + (1 + p[2]) * 64;
break;
}
default:
{
next.code = p[0] + 1 + (p[1] + 1) * 8 + (p[2] + 1) * 64 + (1 + p[3]) * 512;
break;
}
}
if(!valid(next)) continue;
if(next.turn == n)return true;
vis[next.turn][next.pos][next.code] = true;
Q.push(next);
}
}
return false;
}
int main()
{
while(scanf("%d", &n) == 1)
{
if(!n) return 0;
memset(day, false, sizeof(day));
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= 16; ++ j) scanf("%d", &day[i][j]);
printf("%d\n", bfs());
}
return 0;
}/*
challenge : 1. the design of state
2. the extention of states
3. the pictures of position
*/

POJ2044 天气预报---状态细则的更多相关文章

  1. 天气预报API(三):免费接口测试(“旧编码”)

    说明 我以参考文章为引子,自己测试并扩展,努力寻找更多的气象API... 本文所有测试均以青岛为例. 本文所列接口城市代码(cityid)参数都使用的 "旧编码": 全国城市代码列 ...

  2. 基于JAVA的全国天气预报接口调用示例

    step1:选择本文所示例的接口"全国天气预报接口" url:https://www.juhe.cn/docs/api/id/39/aid/87step2:每个接口都需要传入一个参 ...

  3. [ActionScript 3.0] AS3调用百度天气预报查询API

    接口说明 根据经纬度/城市名查询天气的结果 接口示例 http://api.map.baidu.com/telematics/v3/weather?location=成都&output=jso ...

  4. 【AS3 Coder】任务七:初涉PureMVC——天气预报功能实现

    转自:http://www.iamsevent.com/post/36.html AS3 Coder]任务七:初涉PureMVC——天气预报功能实现 使用框架:AS3任务描述:了解PureMVC框架使 ...

  5. 毕业设计--天气预报App

    9月中旬,开始动手做我的毕业设计了,之前一直在纠结做啥,后来想想,既然是做毕业设计,那就大胆地做点自己没接触过的东西吧.然后网上查找资料得知做天气预报需要用到开放的API,而且要用那种现在还在维护的, ...

  6. JTable常见用法细则+设置某列可编辑+滚动表格

    JTable常见用法细则 JTable是Swing编程中很常用的控件,这里总结了一些常用方法以备查阅.欢迎补充,转载请注明作者与出处. 一.创建表格控件的各种方式: 1)  调用无参构造函数. JTa ...

  7. 天气类API调用的代码示例合集:全国天气预报、实时空气质量数据查询、PM2.5空气质量指数等

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 全国天气预报:数据来自国家气象局,可根据地名.经纬度GPS.IP查 ...

  8. Android通过聚合数据API实现天气预报

    使用聚合数据的API 聚合数据地址:https://www.juhe.cn/ 在数据服务->生活常用->全国天气预报,申请天气预报的API使用的KEY 保存请求示例的地址,把您申请的KEY ...

  9. [Android] 免费天气预报接口

    [Android] 免费天气预报接口 这是 国家气象局提供的天气预报接口 [免费] 当然,网上有很多的收费API或者每天定次数的接口 使用 国家气象局 的步骤如下: 1.首先获取城市ID号 北京:10 ...

随机推荐

  1. 对oracle里面clob字段里面xml的增删改查学习

    这段时间,我使用系统表里面有clob字段里面存放的xml信息,我们如何对xml进行增删改查操作呢,自己参考了很多也学到很多,给大家分享一下 首先我们先建测试表 CREATE TABLE EFGP_23 ...

  2. FastJson反序列化和构造函数之间的一点小秘密

    各位看官大家下午好,FastJson想必大家都很熟悉了,很常见的Json序列化工具.今天在下要和大家分享一波FastJson反序列化和构造函数之间的一点小秘密. 下面先进入大家都深恶痛绝的做题环节.哈 ...

  3. php--php设计模式留存

    装饰者模式 <?php interface Decorator { public function display(); } class XiaoFang implements Decorato ...

  4. JavaScript中||和&&的运算

    一般来讲 && 运算和 | | 运算得到的结果都是 true 和 false ,但是 js 中的有点不太一样.当进行 a&&b 和 a| |b (如 1&&am ...

  5. 曹工说Redis源码(4)-- 通过redis server源码来理解 listen 函数中的 backlog 参数

    文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...

  6. wireshark抓包实战(三),界面菜单管理

    1.默认列的增删查改 (1)增加列 选中某个关键词,然后右键应用为列 (2)修改列 选中某个列,右键编辑列 (3)删除列 选中某个列,然后选择移除该列 2.修改时间显示格式 依次选中"视图& ...

  7. IDEA使用技巧,如何在JSP中创建Servlet“小程序”

    步骤 1.新建一个java类,实现Servlet接口 2.实现接口中的抽象方法: 3.在web.xml文件中配置好servlet <web-app ......> <servlet& ...

  8. Android Google Play app signing 最终完美解决方式

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/105561341 本文出自[赵彦军的博客] 在 GooglePlay 创建 App ...

  9. 来说说Java中String 类的那些事情

    今天正好学校那边的任务不多,我就打算把Stirng 的有关知识点都总结在一起了,这样有利于知识的系统性,要不然学多了就会越来越杂,最主要的是总会忘记,记忆的时间太短了,通过这种方式,把它归纳在一起,写 ...

  10. TensorFlow保存、加载模型参数 | 原理描述及踩坑经验总结

    写在前面 我之前使用的LSTM计算单元是根据其前向传播的计算公式手动实现的,这两天想要和TensorFlow自带的tf.nn.rnn_cell.BasicLSTMCell()比较一下,看看哪个训练速度 ...