[Nwerc2015]Hole in One一杆进洞

Description
Janine recently went to her local game store and bought “Hole in One”, a new mini-golf game for her computer. As indicated by the name, the objective of the game is to shoot a ball into a hole using just one shot. The game also borrows elements from brick breaker style games: in the playing field, several walls are placed that will be destroyed upon being hit by the ball. The score of a successful shot depends on the number of destroyed walls, so Janine wonders: what is the maximum number of walls that can be hit while performing a “Hole in One”?
For the purposes of this problem you can think of the playing field as a cartesian plane with the initial position of the ball at the origin. The walls are non-intersecting axis-parallel line segments in this plane (i.e., parallel to either the x axis or the y axis). The diameter of the ball is negligible so it is represented as a single point.
Figure 1: Illustration of the first sample input: The ball first bounces off two walls at points 1 and 2. When it passes point 3 the wall has already vanished.
Whenever the ball hits a wall, two things happen:
The direction of the ball changes in the usual way: the angle of incidence equals the angle of reflection.
The wall that the ball touched is destroyed. Following common video game logic, no rubble of the wall remains; it will be as though it vanished.
The behaviour of the ball is also affected by the power of the shot. In particular, an optimal shot may need to first roll over the hole, then hit some more walls, and only later drop into the hole.
The input consists of:
one line with one integer n (0≤n≤8), the number of walls;
one line with two integers x and y, the coordinates of the hole;
nn lines each with four integers x1, y1, x2, and y2 (either x1=x2, or y1=y2, but not both), representing a wall with end points (x1,y1) and (x2,y2).
The hole is not at the origin and not on a wall. The walls do not touch or intersect each other. No wall lies completely on the x axis or the y axis. All coordinates in the input are integers with absolute value at most 1000.
If there is no way to shoot the ball such that it reaches the hole, print “impossible”. Otherwise, print the maximum number of walls that can be destroyed in a single “Hole in One” shot.
珍妮最近去当地的游戏商店买了“一杆进洞”,一个新的迷你高尔夫电脑游戏。正如名称所示,这个游戏的目标是,将球只用一击击进洞里。游戏还借鉴了打砖块风格的游戏元素:在场上,放置了一些墙,它们被球击中就会被摧毁。一个成功的击球的得分取决于破坏墙的数量,所以珍妮不禁要问:在一次“一杆进洞”中能够摧毁的最多的墙数量是多少?
对于这个问题的意向,你可以认为,比赛场地为笛卡尔坐标平面,球的最初位置在原点。墙壁为在该平面中互不相交且与坐标轴平行的线段(即平行于x轴或y轴)。球的直径非常小以至于把它当成一个点。
图1:第一个样例输入的插图:球首先经过1,2号点,并在3号点时穿过了被摧毁的墙。
每当球碰到一堵墙,会发生:
球的方向以通常的方式改变:入射角等于反射角。
被球触碰的墙被破坏。 游戏逻辑规定,没有墙的废墟存在,认为它消失了。
球的行为也受到击球的力影响。特别的是,最佳的击球可能需要将鼠标放在洞上,然后摧毁一些墙壁,并且只是延迟入洞。
Input
一行一个整数n(0≤n≤8),墙壁的数量。
一行两个整数x和y,洞的坐标。
n行,每行各有四个整数x1,y1,x2与y2(x1 = x2或y1 = y2,但不会满足两者),表示墙壁的两个端点。
洞不会在原点也不会在墙上。墙壁不会互相接触或交叉。没有墙会完全在x轴或y轴上。输入的所有的坐标都是整数且绝对值最大1000。
Output
如果没有办法一击入洞,输出“impossible”。否则,输出在一次“一杆进洞”中能够摧毁的最多的墙的数量。
Sample Input
Sample Input 1
3
4 2
1 1 1 2
2 1 2 2
3 1 3 2
Sample Input 2
1
2 0
1 -1 1 1
Sample Input 3
2
-2 4
2 4 2 2
0 6 -2 6
Sample Output
Sample Output 1
2
Sample Output 2
Impossible
Sample Output 3
2

Solution
首先从大到小枚举答案,再答案!枚举方案,通过镜面对称终点得到路线,然后平方验证路线
注意细节

Code

#include <bits/stdc++.h>
using namespace std;
#define MS(_) memset(_,0,sizeof(_))
template<typename T> inline void read(T &x){x=0; T f=1; char ch=getchar();while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar(); }while (isdigit(ch))  {x=x*10+ch-'0'; ch=getchar(); }x*=f;
}const int INF=0x7fffffff;
const int MaxN=100;
const double eps=0;
struct Vec{double x,y;Vec(){}Vec(double _x,double _y):x(_x),y(_y){}
}p1[MaxN],p2[MaxN],T,p[MaxN];
inline Vec operator + (const Vec &a,const Vec &b){return Vec(a.x+b.x,a.y+b.y);}
inline Vec operator - (const Vec &a,const Vec &b){return Vec(a.x-b.x,a.y-b.y);}
template<typename T>inline Vec operator * (const Vec &a,T b){return Vec(a.x*b,a.y*b);}
template<typename T>inline Vec operator * (T &a,const Vec &b){return Vec(a*b.x,a*b.y);}
template<typename T>inline Vec operator / (const Vec &a,T b){return Vec(a.x/b,a.y/b);}
inline double cross(const Vec &a,const Vec &b){return a.x*b.y-b.x*a.y;}
inline double dot(const Vec &a,const Vec &b){return a.x*b.x+a.y*b.y;}
typedef Vec Poi;
int n,N,type[MaxN],used[MaxN],vis[MaxN],lst[MaxN],ans;inline Poi calnxt(const Vec &a,int no){return type[no]?Vec(a.x,p1[no].y*2-a.y):Vec(p1[no].x*2-a.x,a.y);}
inline Vec caldot(Poi a,Poi b,Poi c,Poi d){if (a.x==b.x){if (c.x==d.x) return Vec(-INF,-INF);if (c.y==d.y) {swap(a,c);swap(b,d);}}    double k=(b.y-a.y)/(b.x-a.x),dt=b.y-k*b.x;if (c.x==d.x) return Vec(c.x,k*c.x+dt);else return Vec((c.y-dt)/k,c.y);
}
inline bool shot(){Poi now=Vec(0.,0.); MS(used);for (int i=N;i;i--){Poi nxt=p[i],wall1=p1[lst[i]],wall2=p2[lst[i]];Poi point=caldot(now,nxt,wall1,wall2);if(dot(point-wall1,point-wall2)>0||dot(point-now,point-nxt)>0) return false;used[lst[i]]=1;for (int j=1;j<=n;j++) if (!used[j]){Poi point2=caldot(now,point,p1[j],p2[j]);if(dot(point2-p1[j],point2-p2[j])<=0&&dot(point2-now,point2-point)<=0) return false;}now=point;}Poi nxt=p[0];for (int j=1;j<=n;j++) if (!used[j]){Poi point2=caldot(now,nxt,p1[j],p2[j]);if(dot(point2-p1[j],point2-p2[j])<=0&&dot(point2-now,point2-nxt)<=0) return false;}return true;
}inline void check(){p[0]=T;for (int i=1;i<=N;i++)p[i]=calnxt(p[i-1],lst[i]);if (shot()) ans=N;
}
void dfs(int dep){if (~ans) return;if (dep>N) {check();return;}for(int i=1;i<=n;i++){if (!vis[i]){vis[lst[dep]=i]=1; dfs(dep+1); vis[i]=0;}if (~ans) return;}
}
int main(){read(n);read(T.x);read(T.y);for(int i=1;i<=n;i++){read(p1[i].x);read(p1[i].y);read(p2[i].x);read(p2[i].y);}for(int i=1;i<=n;i++) if (p1[i].x==p2[i].x){type[i]=0; if (p1[i].y>p2[i].y) swap(p1[i],p2[i]);}else{type[i]=1; if (p1[i].x>p2[i].x) swap(p1[i],p2[i]);}ans=-1;for(int i=n;i>=0;i--){N=i; dfs(1); if (~ans) break;}if (!~ans) puts("impossible"); else printf("%d\n",ans);return 0;
}

[BZOJ4431][Nwerc2015]Hole in One一杆进洞相关推荐

  1. 【bzoj4431】[Nwerc2015]Hole in One一杆进洞

    Problem Description Janine recently went to her local game store and bought "Hole in One", ...

  2. [转载]看外国人在网络上的吐槽:为什么中文这么TM难?

    来源:http://bbs.huanqiu.com/thread-565906-1-1.html 中文标题:为什么中文这么TM难?  原文标题:Why Chinese Is So Damn Hard? ...

  3. 【无标题】物联网安全挑战:为什么企业现在必须评估它们

    企业对物联网 (IoT) 的依赖正在增长,这不仅是向用户推送服务的一种手段,而且是维持与员工.合作伙伴.承包商甚至竞争对手的联系的一种手段.但人们越来越担心,组织急于从物联网中获得回报,而没有完全理解 ...

  4. 做游戏,学编程(C语言) 21 台球

    分享16级同学大一上学期实现的台球游戏,选择了花式九球并简化规则,侧重台球碰撞.进洞的实现与模拟,加入了双人游戏机制.分步骤代码.可执行程序.录屏效果可以从百度网盘下载:http://pan.baid ...

  5. 最牛茅台投资人的一席真言

    最牛茅台投资人的一席真言(转载) 巴菲特说:"一个投资人只需要有两个能力,估值能力,看市场价格的能力."巴菲特在挑选接班人的条件时给出三个条件:"第一,独立思考:第二,情 ...

  6. 微信小程序如何上拉加载下一页

    变量 data: {videos: [],page: 1,pageSize: 8,isLastPage: false,tips: '上拉加载更多' }, videos 数据容器 page 当前页数 p ...

  7. 创业的捷径!打造黄金人脉!

    顶尖金融经理人的关系学 打造黄金人脉 策划·天下工作室 主笔·本刊记者 朱雪尘 世界上有三种人不会嫉妒你的成功:父母亲.中小学老师.风险投资家. 投资家,这些与黄金紧密联系在一起的人,和他们交上朋友可 ...

  8. 论坛上的所有泡MM技巧

    看到好多朋友问怎么泡妞 今天刚好在别的论坛上看到这么一篇文章 ======================================= 初次约会要注意什么?: 1:每个女孩子注重的方面都不一样, ...

  9. 马云和他的阿里巴巴------写在阿里巴巴上市之前

    马云静静地站着,双手拄着一号木高尔夫球杆.对于这位瘦小.单薄的中年男子来说,春天的早晨还是有些凉意:深蓝色的长袖T恤外套着粉红的短衣. 往前开!球带着彩烟冲进水里.球场董事长宋矿满说,这意味着事业上三 ...

最新文章

  1. (转)Spring中ThreadLocal的认识
  2. JavaScript实现Apache .htaccess 转化nginx生成器工具-toolfk程序员工具网
  3. setInterval设置停止和循环
  4. webpack.config.js和package.json
  5. vue底部跳转_详解Vue底部导航栏组件
  6. 计算机基础ABCDEF,计算机应用基础_在线作业ABCDEF.docx
  7. 信息学奥赛一本通 1123:图像相似度 | OpenJudge NOI 1.8 06:图像相似度
  8. 一文弄懂“分布式锁”
  9. 电子密封胶正常固化与非正常固化差别是什么?
  10. 强悍的 Linux —— 权限管理(组及用户管理)
  11. SQL:postgresql增加自增字段
  12. 特朗普“能源独立”政策效果存疑
  13. U盘“请将磁盘插入U盘”的问题
  14. uniapp 微信授权 登陆
  15. WordPress主题可视化建站The7 V8.7
  16. APP——adb命令——背诵实操——背诵总结
  17. EXCEL/WPS中的数组公式{},在钉钉用什么进行替代
  18. [独立游戏][纳税]个人独立游戏缴税纳税相关问题
  19. linux串口ttys1,linux ttySx 应用
  20. 手把手教你用 Tauri+Vue 创建小型桌面应用

热门文章

  1. JVM-Shenandoah GC-29
  2. jdk9,10,11,12没有jre安装方法
  3. 如何做好销售一线的基层管理?
  4. OpenCV实现图像转换为素描效果
  5. 【css】媒体查询(总结)
  6. Android Hook式插件化教程(一)Hook从入门到精通
  7. 想要在PDF文档中提取签名和图像信息?有这篇Aspose.PDF for .NET干货教程就够了!
  8. 卷积神经网络(CNN)探究
  9. 现场直击 | 我眼中的CES 2019
  10. Http协议:三次握手和四次挥手