【NOIP2016提高组】愤怒的小鸟
https://www.luogu.org/problem/show?pid=2831
BFS
看到N这么小就可以想到搜索,求最少步数显然应该用BFS。
在这题中过两猪可以唯一确定一条抛物线,每一步可以发射两只猪确定的一条抛物线(打下这条抛物线上的所有猪),也可以发射一条只经过一只猪的抛物线(只打下这只猪)。
这时可以想到状压存储每个状态,并且读入所有猪时预处理一下每两只猪确定的抛物线。
两点确定一条过原点的抛物线y=ax2+bx的方法:点(x1, y1) (x2, y2)过抛物线,得y1=ax12+bx1,y2=ax22+bx2,两式分别变形得y1/x1-ax1=y2/x2-ax2=b,再整理得a=(y2/x2-y1/x1)/(x2-x1)。求出a后往回代可求出b。
记得记录每个状态是否已经搜索过,避免重复的状态入队。由于共有2n个状态,故时间复杂度是O(2n)的。如果不剪枝就是O(n!)。
题目给的m应该是用来xjb剪枝用的,但是m=2怎么用我也不懂……
注意事项:
- 判断两个浮点数相等要考虑精度误差。
- stl的queue不开优化会很慢,可以考虑手写队列。
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
bool equal(double x, double y, double eps = 1e-)
{
return fabs(x - y) <= eps;
}
int n;
bool m[];
pair<double, double> pigs[];
unsigned target; // 搜索的最终目标,即第1~n位均为1
unsigned pwxs[][]; // pwxs[i][j] => i、j两只猪所在抛物线上的所有猪
bool visited[( << )];
int bfs()
{
typedef pair<unsigned, int> state; // <状态, 步数>
queue<state> q;
q.push(make_pair(, ));
while (!q.empty())
{
state x = q.front();
q.pop(); // 用一只鸟打一只猪的情况
for (int i = ; i <= n; i++)
{
if (!(x.first & ( << i))) // 如果i猪还没被打下
{
state y = x;
y.first |= ( << i);
y.second++;
if (y.first == target)
return y.second;
if (!visited[y.first] && !(m[] && y.second > (int)(n * 1.0 / + )))
{
q.push(y);
visited[y.first] = true;
}
}
} // 用一只鸟打两只猪的情况
for (int i = ; i <= n; i++)
{
for (int j = i + ; j <= n; j++)
{
if (!(x.first & ( << i)) && !(x.first & ( << j))) // 如果i、j猪都还没被打下
{
state y = x;
y.first |= pwxs[i][j];
y.second++;
if (y.first == target)
return y.second;
if (!visited[y.first] && !(m[] && y.second > (int)(n * 1.0 / + )))
{
q.push(y);
visited[y.first] = true;
}
}
}
}
}
return -;
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
memset(visited, false, << ); int c;
cin >> n >> c;
m[c] = true; for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
pwxs[i][j] = ; target = ;
for (int i = ; i <= n; i++)
target |= ( << i); double a, b;
for (int i = ; i <= n; i++)
{
cin >> a >> b;
pigs[i] = make_pair(a, b);
} for (int i = ; i <= n; i++)
{
for (int j = i + ; j <= n; j++)
{
/* ∵ y1=ax1^2+bx1, y2=ax2^2+bx2
∴ b=y1/x1-ax1=y2/x2-ax2
∴ a=(y2/x2-y1/x1)/(x2-x1) */
double &x1 = pigs[i].first, &y1 = pigs[i].second;
double &x2 = pigs[j].first, &y2 = pigs[j].second;
a = (y2 / x2 - y1 / x1) / (x2 - x1);
b = y1 / x1 - a * x1;
if (a < )
{
for (int k = ; k <= n; k++)
{
double &x = pigs[k].first, &y = pigs[k].second;
if (equal(a * x * x + b * x, y))
pwxs[i][j] |= ( << k);
}
}
}
}
cout << bfs() << endl;
}
return ;
}
看到N这么小就可以想到搜索,求最少步数显然应该用BFS。
在这题中过两猪可以唯一确定一条抛物线,每一步可以发射两只猪确定的一条抛物线(打下这条抛物线上的所有猪),也可以发射一条只经过一只猪的抛物线(只打下这只猪)。
这时可以想到状压存储每个状态,并且读入所有猪时预处理一下每两只猪确定的抛物线。
记得记录每个状态是否已经搜索过,避免重复的状态入队。
【NOIP2016提高组】愤怒的小鸟的更多相关文章
- [NOIp2016提高组]愤怒的小鸟
题目大意: 平面直角坐标系的第一象限有n(n<=18)个点,你可以每次给出一个形如y=ax^2+bx的函数把经过这条函数的点消掉,问消掉所有的点至少要多少函数? 思路: 枚举每两个点对,可以唯一 ...
- 【题解】NOIP2016提高组 复赛
[题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...
- 【题解】NOIP2016 提高组 简要题解
[题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
- 【NOIP2016提高组】 Day2 T3 愤怒的小鸟
题目传送门:https://www.luogu.org/problemnew/show/P2831 说个题外话:NOIP2014也有一道题叫做愤怒的小鸟. 这题自测时算错了eps,导致被卡了精度,从1 ...
- NOIP2016提高组复赛C 愤怒的小鸟
题目链接:http://uoj.ac/problem/265 题目大意: 太长了不想概括... 分析: 状压DP的模板题,把所有可能的抛物线用二进制表示,然后暴力枚举所有组合,详情见代码内注释 代码如 ...
- 【NOIP2016提高组day2】愤怒的小鸟
分析 Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 (0, 0) 处,每次Kiana可以用它向第一象限发射一只红色的小鸟, 小鸟们的飞行轨迹均 ...
- 【noip2016提高组day2T3】【愤怒的小鸟】状压dp转移时的集合包含
(上不了p站我要死了,图来自百度,侵权度娘背锅) 调死我了... 标题就说明了,死在了集合包含上.因为这道题与其他的状压题不同,其他的题基本上都是要求集合不重合,而这道题完全是可以的. 废话不多说,先 ...
随机推荐
- 两个HTML地址栏传中文参数乱码
这个不叫乱码,我非专业.这个是url编码,js本身就是读取url编码的.对于js获取url的中文你可以尝试用escape() encodeURI() encodeURIComponent() deco ...
- ASP.NET没有魔法——ASP.NET Identity的加密与解密
前面文章介绍了如何使用Identity在ASP.NET MVC中实现用户的注册.登录以及身份验证.这些功能都是与用户信息安全相关的功能,数据安全的重要性永远放在第一位.那么对于注册和登录功能来说要把密 ...
- Ellipse
Description There is an beautiful ellipse whose curve equation is: b > 0)" src="http:// ...
- hdu 3555 Bomb(不要49,数位DP)
Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submi ...
- Linux学习(十七)压缩与打包
一.关于打包和压缩 打包和压缩的最大意义在于减少文件传输中需要的流量.打包的方式大概有tar命令,zip命令.压缩的方式有gzip,bzip2,xz.tar命令可以通过参数将压缩和打包在一起执行. 二 ...
- MySQL-client-5.6.36-1.linux_glibc2.5.x86_64.rpm安装详解
centos6.8已经安装了mysql,所以要卸载掉 查看命令 rpm -qa | grep mysql 注意:MySQL区分大小写 grep mysql 和grep MySQL 是不一样的!! 卸载 ...
- kettle闪退问题
确定Java的配置环境没问题 kettle闪退的时候把spoon.bat里面的配置项改一下 if "%PENTAHO_DI_JAVA_OPTIONS%"=="" ...
- Even Tree 小议
原题链接:https://www.hackerrank.com/challenges/even-tree/problem 思路:把树还原出来,对每个结点,计算以该结点为根的子树结点数.子树结点数为偶数 ...
- eclipse中删除多余的tomcat server
在eclipse菜单中选择Window--Show View--Server--Servers,打开这个服务窗口,将多余的服务删除即可. 如果每次启动中太卡没反应,那就是服务没选择好,或是端口冲突的原 ...
- Photoshop颜色出现比较大的偏差,偏色严重,显示器配置文件2351似乎有问题
其实出现这个问题是因为 显示器的配置问题.并不是PS版本或者电脑系统问题. 一般在你首次启动PS的时候会出现提示:显示器配置文件2351似乎有问题. 如果你点击了继续运行那以后你使用PS打开任何文件都 ...