NOIP2016提高组复赛C 愤怒的小鸟
题目链接:http://uoj.ac/problem/265
题目大意:
太长了不想概括。。。
分析:
状压DP的模板题,把所有可能的抛物线用二进制表示,然后暴力枚举所有组合,详情见代码内注释
代码如下:
- #pragma GCC optimize("Ofast")
- #include <bits/stdc++.h>
- using namespace std;
- #define INIT() std::ios::sync_with_stdio(false);std::cin.tie(0);
- #define Rep(i,n) for (int i = 0; i < (n); ++i)
- #define For(i,s,t) for (int i = (s); i <= (t); ++i)
- #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
- #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
- #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
- #define pr(x) cout << #x << " = " << x << " "
- #define prln(x) cout << #x << " = " << x << endl
- #define LOWBIT(x) ((x)&(-x))
- #define ALL(x) x.begin(),x.end()
- #define INS(x) inserter(x,x.begin())
- #define ms0(a) memset(a,0,sizeof(a))
- #define msI(a) memset(a,inf,sizeof(a))
- #define msM(a) memset(a,-1,sizeof(a))
- #define pii pair<int,int>
- #define piii pair<pair<int,int>,int>
- #define MP make_pair
- #define PB push_back
- #define ft first
- #define sd second
- template<typename T1, typename T2>
- istream &operator>>(istream &in, pair<T1, T2> &p) {
- in >> p.first >> p.second;
- return in;
- }
- template<typename T>
- istream &operator>>(istream &in, vector<T> &v) {
- for (auto &x: v)
- in >> x;
- return in;
- }
- template<typename T1, typename T2>
- ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
- out << "[" << p.first << ", " << p.second << "]" << "\n";
- return out;
- }
- inline int gc(){
- static const int BUF = 1e7;
- static char buf[BUF], *bg = buf + BUF, *ed = bg;
- if(bg == ed) fread(bg = buf, , BUF, stdin);
- return *bg++;
- }
- inline int ri(){
- int x = , f = , c = gc();
- for(; c<||c>; f = c=='-'?-:f, c=gc());
- for(; c>&&c<; x = x* + c - , c=gc());
- return x*f;
- }
- typedef long long LL;
- typedef unsigned long long uLL;
- typedef pair< double, double > PDD;
- typedef set< int > SI;
- typedef vector< int > VI;
- const double EPS = 1e-;
- const int inf = 1e9 + ;
- const LL mod = 1e9 + ;
- const int maxN = 1e5 + ;
- const LL ONE = ;
- int sgn(double x) {
- if(fabs(x) < EPS) return ;
- return x > ? : -;
- }
- struct Matrix{
- double m[][];
- Matrix(){}
- Matrix(double x11, double x12, double x21, double x22) {
- m[][] = x11;
- m[][] = x12;
- m[][] = x21;
- m[][] = x22;
- }
- double det() {
- return m[][] * m[][] - m[][] * m[][];
- }
- };
- int T, n, m, ans;
- PDD pig[];
- // 用n位二进制数记录一条抛物线可能穿过的点的状态
- // 比如抛物线过1号,5号,7号点,那么数值为 :000000000001010001
- VI state;
- SI si;
- // f[i]为当前状态的最小步数
- int f[ << ];
- int bitcount32(int bits) {
- bits = (bits & 0x55555555) + (bits >> & 0x55555555);
- bits = (bits & 0x33333333) + (bits >> & 0x33333333);
- bits = (bits & 0x0f0f0f0f) + (bits >> & 0x0f0f0f0f);
- bits = (bits & 0x00ff00ff) + (bits >> & 0x00ff00ff);
- return (bits & 0x0000ffff) + (bits >> & 0x0000ffff);
- }
- // 通过2个点算抛物线参数[a, b]
- bool calcAB(PDD x, PDD y, PDD ¶) {
- Matrix D = Matrix(x.ft * x.ft, x.ft, y.ft * y.ft, y.ft);
- if(sgn(D.det()) == ) return false;
- Matrix D1 = Matrix(x.sd, x.ft, y.sd, y.ft);
- Matrix D2 = Matrix(x.ft * x.ft, x.sd, y.ft * y.ft, y.sd);
- para.ft = D1.det() / D.det();
- if(sgn(para.ft) >= ) return false;
- para.sd = D2.det() / D.det();
- return true;
- }
- // 验证点x是否符合抛物线
- bool check(PDD x, PDD ¶) {
- if(sgn(para.ft * x.ft * x.ft + para.sd * x.ft - x.sd) == ) return true;
- return false;
- }
- void solve() {
- int ret = ;
- // 枚举所有点对
- For(i, , n) {
- For(j, i + , n) {
- PDD p;
- if(!calcAB(pig[i], pig[j], p)) continue;
- // 看是否有其他点也经过这条抛物线
- int st = ;
- st |= << (i - );
- st |= << (j - );
- For(k, , n) {
- if(k == i || k == j) continue;
- if(check(pig[k], p)) st |= << (k - );
- }
- if(si.find(st) == si.end()) {
- si.insert(st);
- state.PB(st);
- }
- }
- }
- // 把只过一个点的抛物线也存一下
- Rep(i, n) state.PB( << i);
- // 把所有抛物线都得到后,问题就变成在这些抛物线中最少能选取几条,进行或运算后二进制1~n位全为1
- msI(f);
- f[] = ;
- int len = state.size();
- Rep(i, << n) {
- // 当枚举到f[i]时,f[i]已经是最优解了
- Rep(j, len) {
- f[i | state[j]] = min(f[i | state[j]], f[i] + );
- }
- }
- ans = f[( << n) - ];
- }
- int main(){
- INIT();
- cin >> T;
- while(T--) {
- state.clear();
- si.clear();
- cin >> n >> m;
- For(i, , n) cin >> pig[i];
- solve();
- cout << ans << endl;
- }
- return ;
- }
NOIP2016提高组复赛C 愤怒的小鸟的更多相关文章
- 【题解】NOIP2016提高组 复赛
[题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
- 破译情报-NOIP2016提高组复赛模拟试题
[题目描述] 最近国安人员截获了一份 RB 国的秘密情报, 全文都是经过加密的,每个单 词都很长.破译人员想到先把单词化简一下,方法是把每个单词尽量取短些的前 缀,但所取的前缀不能是其他单词的前缀. ...
- 【NOIP2016提高组复赛day2】天天爱跑步
题目 小 C 同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏. <天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一棵 ...
- 【NOIP2016提高组day2】愤怒的小鸟
分析 Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 (0, 0) 处,每次Kiana可以用它向第一象限发射一只红色的小鸟, 小鸟们的飞行轨迹均 ...
- 【题解】NOIP2016 提高组 简要题解
[题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
- 【题解】NOIP2015提高组 复赛
[题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...
- NOIP2016普及组复赛解题报告
提高组萌新,DAY1DAY2加起来骗分不到300,写写普及组的题目聊以自慰. (附:洛谷题目链接 T1:https://www.luogu.org/problem/show?pid=1909 T2:h ...
随机推荐
- java 关于打断点
比如:前台传过来参数中文乱码,需要decode才可以使用, 判断问题. debug 在 DispatcherServlet OncePerRequestFilter 打断点, 查看前台过来的中文在哪里 ...
- centos7下kubernetes(4.kubernetes组件)
Kubenetes cluster 由master和node组成 Master是kubenetes的大脑.运行着以下进程:kube-apiserver.kube-scheduler.kube-cont ...
- vue 数据绑定实现的核心 Object.defineProperty()
vue深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简 ...
- ansible的playbook进行yum批量安装nginx最新版本
环境:centos7 版本:nginx最新版本 软件: ansible 作用: 进行批量执行不同机器上,进行安装nginx版本 检查脚本是否正确: [root@ansible-test ansible ...
- 第11章 AOF持久化
AOF持久化在硬盘上保存的是对Redis进行的逻辑操作,类似InnoDB中的bin log.说白了就是你对一个Redis输入了哪些语句,AOF文件都会原封不动的保存起来,等到需要回复Redis的时候再 ...
- mysql锁2
死锁: 指两个事务或者多个事务在同一资源上相互占用,并请求对方所占用的资源,从而造成恶性循环的现象. 出现死锁的原因: 系统资源不足: 进程运行推进的顺序不当: 资源分配不当. 产生死锁的四个必要条件 ...
- 操作循环的关键字switch,break,return的应用及区别
break 使用break结束循环 break可以终止循环 和 switch语句的运行; break用于结束一个循环,即跳出循环体,执行循环体之后的代码: switch 使用continue提前结束 ...
- 教你使用HTML5原生对话框元素,轻松创建模态框组件
HTML 5.2草案加入了新的dialog元素.但是是一种实验技术. 以前,如果我们想要构建任何形式的模式对话框或对话框,我们需要有一个背景,一个关闭按钮,将事件绑定在对话框中的方式安排我们的标记,找 ...
- 分解质因数FZU - 1075
题目简述:就是给一个数,把他拆分成多个素数的乘积,这正好是算术基本定理.本题我的解决方法是埃氏素数筛+质因数保存...开始T掉了,是因为我在最后枚举了素数,保存他们的次数,然后两次for去查询他们的次 ...
- Day11 Python基础之装饰器(高级函数)(九)
在python中,装饰器.生成器和迭代器是特别重要的高级函数 https://www.cnblogs.com/yuanchenqi/articles/5830025.html 装饰器 1.如果说装 ...