紫书 例题7-14 UVa 1602(搜索+STL+打表)
这道题想了很久不知道怎么设置状态,怎么拓展,怎么判重, 最后看了这哥们的博客 终于明白了。
https://blog.csdn.net/u014800748/article/details/47400557
这道题的难点在于怎么设置联通的状态,以及怎么拓展判重 .
(1)状态:这里状态先定义了一个格子cell, 有x和y坐标。然后set<cell>表示一个联通块, 再用set<set<cell>>表示n个连块可以组成的所有联通块, 这里是集合套集合。
(2)拓展:每个格子向四个方向拓展。平移方面用到了标准化,感性的认识就是把这个图形整个移到了左下角(具体看代码), 然后旋转,这里有一个规律,就是所有的格子都是 (x, y) -> (y, -x) ,每次执行都会旋转90度,记得最后返回的是标准化后的图形。翻转的话,沿x轴翻转, 即(x, y)-> (x, -y), 然后再旋转四次,其中旋转180度后即是y轴翻转的结果,已经包含在里面了,所以不用另外写。
(3)最后就是打表,在多组数据而每组数据程序运行的时候会做重复的事情的时候,用打表会比直接做更快一些
代码如下
#include<cstdio>
#include<algorithm>
#include<set>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
struct cell
{
int x, y;
cell(int x = 0, int y = 0) : x(x), y(y) {}
bool operator < (const cell& rhs) const
{
return x < rhs.x || (x == rhs.x && y < rhs.y); //固定写法
}
};
const int MAXN = 11;
typedef set<cell> piece;
int ans[MAXN][MAXN][MAXN];
set<piece> poly[MAXN];
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
inline piece normalize(piece p0)
{
int minx = 15, miny = 15; //最大也就10,这里表示最大值
for(auto& t : p0)
{
minx = min(minx, t.x);
miny = min(miny, t.y);
}
piece ret;
for(auto& t : p0) ret.insert(cell(t.x - minx, t.y - miny)); //这种遍历方式要c++11, 编译选项要加入-std=c++11
return ret;
}
inline piece rotate(piece p0)
{
piece ret;
for(auto& t : p0) ret.insert(cell(t.y, -t.x));
return normalize(ret);
}
inline piece file(piece p0)
{
piece ret;
for(auto& t : p0) ret.insert(cell(t.x, -t.y));
return normalize(ret);
}
void add(piece p0, cell c)
{
piece p = p0;
p.insert(c);
p = normalize(p);
int id = p.size();
REP(i, 0, 4)
{
if(poly[id].count(p)) return;
p = rotate(p);
}
p = file(p);
REP(i, 0, 4)
{
if(poly[id].count(p)) return;
p = rotate(p);
}
poly[id].insert(p);
}
void work()
{
piece start;
start.insert(cell(0, 0));
poly[1].insert(start);
REP(n, 2, MAXN)
for(auto& p : poly[n-1]) // 这里n-1,因为是从前一个拓展过来的
for(auto& t : p)
REP(i, 0, 4)
{
cell temp(t.x + dir[i][0], t.y + dir[i][1]);
if(!p.count(temp)) add(p, temp);
}
REP(n, 1, MAXN)
REP(w, 1, MAXN)
REP(h, 1, MAXN)
{
int cnt = 0;
for(auto& p : poly[n])
{
int maxx = 0, maxy = 0;
for(auto & t : p)
{
maxx = max(maxx, t.x);
maxy = max(maxy, t.y);
}
if(max(maxx, maxy) < max(w, h) && min(maxx, maxy) < min(w, h)) cnt++; //是否符合题目要求
}
ans[n][w][h] = cnt;
}
}
int main()
{
work();
int n, w, h;
while(~scanf("%d%d%d", &n, &w, &h))
printf("%d\n", ans[n][w][h]); //提前打表
return 0;
}
紫书 例题7-14 UVa 1602(搜索+STL+打表)的更多相关文章
- 紫书 例题 11-13 UVa 10735(混合图的欧拉回路)(最大流)
这道题写了两个多小时-- 首先讲一下怎么建模 我们的目的是让所有点的出度等于入度 那么我们可以把点分为两部分, 一部分出度大于入度, 一部分入度大于出度 那么显然, 按照书里的思路,将边方向后,就相当 ...
- 紫书 例题8-3 UVa 1152(中途相遇法)
这道题要逆向思维, 就是求出答案的一部分, 然后反过去去寻找答案存不存在. 其实很多其他题都用了这道题目的方法, 自己以前都没有发现, 这道题专门考这个方法.这个方法可以没有一直往下求, 可以省去很多 ...
- 紫书 例题8-12 UVa 12627 (找规律 + 递归)
紫书上有很明显的笔误, 公式写错了.g(k, i)的那个公式应该加上c(k-1)而不是c(k).如果加上c(k-1)那就是这一次 所有的红气球的数目, 肯定大于最下面i行的红气球数 我用的是f的公式, ...
- 紫书 例题8-4 UVa 11134(问题分解 + 贪心)
这道题目可以把问题分解, 因为x坐标和y坐标的答案之间没有联系, 所以可以单独求两个坐标的答案 我一开始想的是按照左区间从小到大, 相同的时候从右区间从小到大排序, 然后WA 去uDebug找了数据 ...
- 紫书 例题8-17 UVa 1609 (构造法)(详细注释)
这道题用构造法, 就是自己依据题目想出一种可以得到解的方法, 没有什么规律可言, 只能根据题目本身来思考. 这道题的构造法比较复杂, 不知道刘汝佳是怎么想出来的, 我想的话肯定想不到. 具体思路紫书上 ...
- 紫书 例题 9-5 UVa 12563 ( 01背包变形)
总的来说就是价值为1,时间因物品而变,同时注意要刚好取到的01背包 (1)时间方面.按照题意,每首歌的时间最多为t + w - 1,这里要注意. 同时记得最后要加入时间为678的一首歌曲 (2)这里因 ...
- 紫书 例题 10-2 UVa 12169 (暴力枚举)
就是暴力枚举a, b然后和题目给的数据比较就ok了. 刘汝佳这道题的讲解有点迷,书上讲有x1和a可以算出x2, 但是很明显x2 = (a * x1 +b) 没有b怎么算x2?然后我就思考了很久,最后去 ...
- 紫书 例题 10-12 UVa 1637(概率计算)
以9元组来代表当前状态,每一元是每一堆剩下的牌数 枚举当前状态所有可以拿掉牌的情况,然后递归下去求 概率,当牌拿完的时候概率为1 那么这里的实现非常的秀,用到了vector来代表9元组 然后还用到了m ...
- 紫书 例题 10-26 UVa 11440(欧拉函数+数论)
这里用到了一些数论知识 首先素因子都大于M等价与M! 互质 然后又因为当k与M!互质且k>M!时当且仅当k mod M! 与M!互质(欧几里得算法的原理) 又因为N>=M, 所以N!为M! ...
随机推荐
- Btrfs 文件系统
btrfs文件系统简介 btrfs文件系统:技术预览版(Centos7) Btrfs(B-tree.Butter FS.Better FS),GPL授权,Orale2007提出是想用来取代Ext文 ...
- 一步步理解linux字符设备驱动框架(转)
/* *本文版权归于凌阳教育.如转载请注明 *原作者和原文链接 http://blog.csdn.net/edudriver/article/details/18354313* *特此说明并保留对其追 ...
- Django入门--创建项目及应用
Django是用于后台处理的web应用框架.用户通过浏览器输入网址,向http服务器发起访问网页的请求,http服务器(Apache/Nginx)接收到用户请求后,把请求发送给web应用框架进行处理, ...
- Android内存管理-SoftReference的使用
本文介绍对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有 ...
- Centos与Ubuntu命令
1.虽然Centos与Ubuntu都是linux的内核,但使用命令还是有所差别 2.如在Centos中跟新插件用的是:yum -y (yum后面有一个空格) 在Ubuntu中跟新插件用的是:apt ...
- CodeForcesGym 100641D Generalized Roman Numerals
Generalized Roman Numerals Time Limit: 5000ms Memory Limit: 262144KB This problem will be judged on ...
- C++ "#"的作用和用法
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/48879093 1 #和##的作用和用法 ...
- MySQL主要的命令(1)
创建数据库 create database db_name; 创建数据库设置字符集 create database db_name character set utf8; 修改字符集编码 数据库导出: ...
- BindingResult不能获取错误对象
BindingResult不能获取错误对象,代码如下: @RequestMapping(value = "/login") public String error4( Model ...
- Android nomedia 避免图片等资源泄露在系统图库其中
总结 Android nomedia 避免文件泄露在系统图库和系统铃声中 在应用开发中 项目的图片总是被系统的图库收录了 避免图片被系统图库收录的发现有2个方法 第一种针对图片 将 .png为后缀的图 ...