【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站我要死了,图来自百度,侵权度娘背锅) 调死我了... 标题就说明了,死在了集合包含上.因为这道题与其他的状压题不同,其他的题基本上都是要求集合不重合,而这道题完全是可以的. 废话不多说,先 ...
随机推荐
- Sequence one
Problem Description Search is important in the acm algorithm. When you want to solve a problem by us ...
- 2016年中国大学生程序设计竞赛(杭州)1006 Four Operations
Four Operations Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- 记录下Webapi签名机制
首先,写这篇文章的原因是因为最近某一个项目中的接口被人为调用了,导致了数据库数据被串改.虽然是内部人无意点的,但还是引起了我的担忧,所有整理了下关于Webapi的相关签名机制. 一.我们在开发接口时, ...
- CLR Via C#: 类型基础
所有类型都从System.Object派生 一下两个类型定义是完全一致的 class Employee { } class Employee : System.Object { } 由于所有类型最终都 ...
- CentOS6软raid配置与管理
事先添加硬盘设备sdb.sdc.sdd.sde.无论是物理硬盘还是虚拟硬盘,最好使用同型号同大小的硬盘. 创建raid设备 支持raid0.1.4.5.6级别 # mdadm -C /dev/md0 ...
- Three ways to throw exception in C#. Which is your preference?
There are three ways to 'throw' a exception in C# C#中有三种抛出异常的方式 Use the throw keyword without an id ...
- 开源API测试工具 Hitchhiker v0.4更新 - 没有做不到,只有想不到
Hitchhiker 是一款开源的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持上传脚本定制请求,可以轻松部署到本地,和你的team成员一起管理Api. 详细介绍 ...
- python列表的一些常用方法以及函数
学习到了一些关于python列表的新知识,自己整理了一下,方便大家参考: #!/usr/bin/env python # _*_ coding:utf-8 _*_ # File_type:列表的常用操 ...
- Cordic算法——圆周系统之向量模式
旋转模式用来解决三角函数,实现极坐标到直角坐标的转换,基础理论请参考Cordic算法--圆周系统之旋转模式.那么,向量模式则用来解决反三角函数的问题,体现的应用主要是直角坐标向极坐标转换,即已知一点的 ...
- 转载--Typecho install.php 反序列化导致任意代码执行
转载--Typecho install.php 反序列化导致任意代码执行 原文链接(http://p0sec.net/index.php/archives/114/) 0x00 前言 漏洞公布已经过去 ...