题目链接:http://uoj.ac/problem/265

题目大意:

  太长了不想概括。。。

分析:

  状压DP的模板题,把所有可能的抛物线用二进制表示,然后暴力枚举所有组合,详情见代码内注释

代码如下:

  1. #pragma GCC optimize("Ofast")
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4.  
  5. #define INIT() std::ios::sync_with_stdio(false);std::cin.tie(0);
  6. #define Rep(i,n) for (int i = 0; i < (n); ++i)
  7. #define For(i,s,t) for (int i = (s); i <= (t); ++i)
  8. #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
  9. #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
  10. #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
  11.  
  12. #define pr(x) cout << #x << " = " << x << " "
  13. #define prln(x) cout << #x << " = " << x << endl
  14.  
  15. #define LOWBIT(x) ((x)&(-x))
  16.  
  17. #define ALL(x) x.begin(),x.end()
  18. #define INS(x) inserter(x,x.begin())
  19.  
  20. #define ms0(a) memset(a,0,sizeof(a))
  21. #define msI(a) memset(a,inf,sizeof(a))
  22. #define msM(a) memset(a,-1,sizeof(a))
  23.  
  24. #define pii pair<int,int>
  25. #define piii pair<pair<int,int>,int>
  26. #define MP make_pair
  27. #define PB push_back
  28. #define ft first
  29. #define sd second
  30.  
  31. template<typename T1, typename T2>
  32. istream &operator>>(istream &in, pair<T1, T2> &p) {
  33. in >> p.first >> p.second;
  34. return in;
  35. }
  36.  
  37. template<typename T>
  38. istream &operator>>(istream &in, vector<T> &v) {
  39. for (auto &x: v)
  40. in >> x;
  41. return in;
  42. }
  43.  
  44. template<typename T1, typename T2>
  45. ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
  46. out << "[" << p.first << ", " << p.second << "]" << "\n";
  47. return out;
  48. }
  49.  
  50. inline int gc(){
  51. static const int BUF = 1e7;
  52. static char buf[BUF], *bg = buf + BUF, *ed = bg;
  53.  
  54. if(bg == ed) fread(bg = buf, , BUF, stdin);
  55. return *bg++;
  56. }
  57.  
  58. inline int ri(){
  59. int x = , f = , c = gc();
  60. for(; c<||c>; f = c=='-'?-:f, c=gc());
  61. for(; c>&&c<; x = x* + c - , c=gc());
  62. return x*f;
  63. }
  64.  
  65. typedef long long LL;
  66. typedef unsigned long long uLL;
  67. typedef pair< double, double > PDD;
  68. typedef set< int > SI;
  69. typedef vector< int > VI;
  70. const double EPS = 1e-;
  71. const int inf = 1e9 + ;
  72. const LL mod = 1e9 + ;
  73. const int maxN = 1e5 + ;
  74. const LL ONE = ;
  75.  
  76. int sgn(double x) {
  77. if(fabs(x) < EPS) return ;
  78. return x > ? : -;
  79. }
  80.  
  81. struct Matrix{
  82. double m[][];
  83.  
  84. Matrix(){}
  85. Matrix(double x11, double x12, double x21, double x22) {
  86. m[][] = x11;
  87. m[][] = x12;
  88. m[][] = x21;
  89. m[][] = x22;
  90. }
  91.  
  92. double det() {
  93. return m[][] * m[][] - m[][] * m[][];
  94. }
  95. };
  96.  
  97. int T, n, m, ans;
  98. PDD pig[];
  99. // 用n位二进制数记录一条抛物线可能穿过的点的状态
  100. // 比如抛物线过1号,5号,7号点,那么数值为 :000000000001010001
  101. VI state;
  102. SI si;
  103. // f[i]为当前状态的最小步数
  104. int f[ << ];
  105.  
  106. int bitcount32(int bits) {
  107. bits = (bits & 0x55555555) + (bits >> & 0x55555555);
  108. bits = (bits & 0x33333333) + (bits >> & 0x33333333);
  109. bits = (bits & 0x0f0f0f0f) + (bits >> & 0x0f0f0f0f);
  110. bits = (bits & 0x00ff00ff) + (bits >> & 0x00ff00ff);
  111. return (bits & 0x0000ffff) + (bits >> & 0x0000ffff);
  112. }
  113.  
  114. // 通过2个点算抛物线参数[a, b]
  115. bool calcAB(PDD x, PDD y, PDD &para) {
  116. Matrix D = Matrix(x.ft * x.ft, x.ft, y.ft * y.ft, y.ft);
  117. if(sgn(D.det()) == ) return false;
  118. Matrix D1 = Matrix(x.sd, x.ft, y.sd, y.ft);
  119. Matrix D2 = Matrix(x.ft * x.ft, x.sd, y.ft * y.ft, y.sd);
  120.  
  121. para.ft = D1.det() / D.det();
  122. if(sgn(para.ft) >= ) return false;
  123. para.sd = D2.det() / D.det();
  124. return true;
  125. }
  126.  
  127. // 验证点x是否符合抛物线
  128. bool check(PDD x, PDD &para) {
  129. if(sgn(para.ft * x.ft * x.ft + para.sd * x.ft - x.sd) == ) return true;
  130. return false;
  131. }
  132.  
  133. void solve() {
  134. int ret = ;
  135.  
  136. // 枚举所有点对
  137. For(i, , n) {
  138. For(j, i + , n) {
  139. PDD p;
  140. if(!calcAB(pig[i], pig[j], p)) continue;
  141. // 看是否有其他点也经过这条抛物线
  142. int st = ;
  143. st |= << (i - );
  144. st |= << (j - );
  145. For(k, , n) {
  146. if(k == i || k == j) continue;
  147. if(check(pig[k], p)) st |= << (k - );
  148. }
  149. if(si.find(st) == si.end()) {
  150. si.insert(st);
  151. state.PB(st);
  152. }
  153. }
  154. }
  155. // 把只过一个点的抛物线也存一下
  156. Rep(i, n) state.PB( << i);
  157. // 把所有抛物线都得到后,问题就变成在这些抛物线中最少能选取几条,进行或运算后二进制1~n位全为1
  158. msI(f);
  159. f[] = ;
  160. int len = state.size();
  161.  
  162. Rep(i, << n) {
  163. // 当枚举到f[i]时,f[i]已经是最优解了
  164. Rep(j, len) {
  165. f[i | state[j]] = min(f[i | state[j]], f[i] + );
  166. }
  167. }
  168.  
  169. ans = f[( << n) - ];
  170. }
  171.  
  172. int main(){
  173. INIT();
  174. cin >> T;
  175. while(T--) {
  176. state.clear();
  177. si.clear();
  178. cin >> n >> m;
  179. For(i, , n) cin >> pig[i];
  180. solve();
  181.  
  182. cout << ans << endl;
  183. }
  184.  
  185. return ;
  186. }

NOIP2016提高组复赛C 愤怒的小鸟的更多相关文章

  1. 【题解】NOIP2016提高组 复赛

    [题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...

  2. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

  3. 破译情报-NOIP2016提高组复赛模拟试题

    [题目描述] 最近国安人员截获了一份 RB 国的秘密情报, 全文都是经过加密的,每个单 词都很长.破译人员想到先把单词化简一下,方法是把每个单词尽量取短些的前 缀,但所取的前缀不能是其他单词的前缀. ...

  4. 【NOIP2016提高组复赛day2】天天爱跑步

    题目 小 C 同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏. <天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一棵 ...

  5. 【NOIP2016提高组day2】愤怒的小鸟

    分析 Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 (0, 0) 处,每次Kiana可以用它向第一象限发射一只红色的小鸟, 小鸟们的飞行轨迹均 ...

  6. 【题解】NOIP2016 提高组 简要题解

    [题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...

  7. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  8. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  9. NOIP2016普及组复赛解题报告

    提高组萌新,DAY1DAY2加起来骗分不到300,写写普及组的题目聊以自慰. (附:洛谷题目链接 T1:https://www.luogu.org/problem/show?pid=1909 T2:h ...

随机推荐

  1. Spring获取实现某接口的所有实例bean

    1.获取 applicationContext,通过ApplicationAware自动注入 2.getBeansOfType.getBeanNamesForType Map<String, I ...

  2. 提高git下载速度(非代理或修改HOST)

    1. 利用开源中国提供的代码仓库 标题已经说的很清楚了,我想对于经常使用git的人来讲,很可能已经知道了.对于新手刚接触git的人来讲,可能你只知道github. 实际上,国内也有很多代码仓库提供方, ...

  3. BZOJ3110:[ZJOI2013]K大数查询(整体二分)

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  4. hive并行执行作业; 强化在脑海的印象

    如果集群资源充足可以设置:set hive.exec.parallel=true; (默认是false) 这样相互独立的job可以并行执行!!!! count(distinct) 最好改写为group ...

  5. js 常用的比较排序算法总结

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 一直很惧怕算法,总是感觉特别伤脑子,因此至今为止,几种基本的排序算法一直都不是很清楚, ...

  6. 5-servlet简介

    一.servlet1.是什么:java程序来处理页面请求和响应2.实现方式: a.实现Servlet接口 b.继承HttpServlet类 3.步骤: a.创建一个java程序实现Servlet或者继 ...

  7. python:利用xlrd模块操作excel

    在自动化测试过程中,对测试数据的管理和维护是一个不可忽视的点.一般来说,如果测试用例数据不是太多的话,使用excel管理测试数据是个相对来说不错的选择. 这篇博客,介绍下如何利用python的xlrd ...

  8. linux内存源码分析 - SLUB分配器概述

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ SLUB和SLAB的区别 首先为什么要说slub分配器,内核里小内存分配一共有三种,SLAB/SLUB/SLOB ...

  9. face recognition[angular/consine-margin-based][L2-Softmax]

    本文来自<L2-constrained Softmax Loss for Discriminative Face Verification>,时间线为2017年6月. 近些年,人脸验证的性 ...

  10. Grafana+Prometheus打造全方位立体监控系统

    前言 本文主要介绍如何使用Grafana和Prometheus以及node_exporter对Linux服务器性能进行监控.下面两张图分别是两台服务器监控信息: 服务器A 服务器B 概述 Promet ...