USACO 2016 December Contest Gold T3: Lasers and Mirrors

题目大意

出于某种原因,农夫约翰的牛总是在举行激光表演。

对于他们的最新展会,奶牛已经购买了一个大功率的激光器 - 这么大,事实上,他们似乎不能轻易地从它交付的位置移动。他们想以某种方式将激光的光发送到FJ物业另一侧的谷仓。激光器和谷仓都可以被认为位于FJ农场的地图上的2D平面中的点上。牛计划指挥激光器,使得它发出水平或竖直(即,与x或y轴平行)的光束。他们会将这个光束从一些镜子反射回去,直接到谷仓。

在农场上有N个栅栏(1≤N≤100,000),位于不同的二维点(也不同于激光和谷仓),牛可以安装镜子。可以选择不在护栏柱上安装镜子,在这种情况下,激光器将简单地直接通过柱子的顶部而不改变方向。如果母牛确实在栅栏柱上安装了一个镜子,它们会像/或\对齐,使得它将在垂直方向上重定向光束,反之亦然。

请计算牛需要使用的镜子的最小可能数量,以便将激光重新导向谷仓。

题目分析

考虑装了镜子后会有什么效果。

若一束光打过来到一个护栏上,沿原方向出去花费为0,改变90°后出去花费为1。

所以考虑把一个点拆成四个点。(这里借用洛谷大佬 _Yunluo_的一张图)(点开后为他滴题解)

这样,蓝色边权为0,橙色边权为1。

至此,我们完成了“装镜子”,这个操作。

然后我们把所有点分别按照横坐标,纵坐标排序,建边。跑一遍最短路就行。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=1e5+10;
 4 const int Inf=0x3f3f3f3f;
 5 struct Node{
 6     int x,y,id;
 7 }p[MAXN+10];
 8 struct Egde{
 9     int to,nxt,d;
10 }e[MAXN<<4];
11 int cnt,head[MAXN<<3];
12 inline void add_edge(int u,int v,int d){
13     e[++cnt].to=v;e[cnt].d=d;e[cnt].nxt=head[u];head[u]=cnt;
14 }
15 inline bool cmp1(Node a,Node b){
16     return a.x==b.x?a.y<b.y:a.x<b.x;
17 }
18 inline bool cmp2(Node a,Node b){
19     return a.y==b.y?a.x<b.x:a.y<b.y;
20 }
21
22 int n,S,T,p_cnt;
23 int new_Node[MAXN][4];
24 int dis[MAXN*4+10];
25 bool vis[MAXN*4+10];
26 queue<int> q;
27 inline void SPFA(){
28     for(int i=1;i<=MAXN*4;++i)
29         dis[i]=Inf;
30     q.push(S);
31     vis[S]=1;
32     dis[S]=0;
33     while(!q.empty()){
34         int x=q.front();
35         q.pop();
36         vis[x]=false;
37         for(int i=head[x],y;i;i=e[i].nxt){
38             y=e[i].to;
39             if(dis[y]>dis[x]+e[i].d){
40                 dis[y]=dis[x]+e[i].d;
41                 if(!vis[y]){
42                     q.push(y);
43                     vis[y]=true;
44                 }
45             }
46         }
47     }
48 }
49
50 int main(){
51     for(int i=1;i<=MAXN;++i) p[i].id=i;
52     scanf("%d%d%d%d%d",&n,&p[1].x,&p[1].y,&p[2].x,&p[2].y);
53     n+=2;
54     for(int i=3;i<=n;++i)
55         scanf("%d%d",&p[i].x,&p[i].y);
56     S=++p_cnt;T=++p_cnt;
57     for(int i=1;i<=n;++i)
58         for(int j=0;j<=3;++j)
59             new_Node[i][j]=++p_cnt;
60     for(int i=1;i<=n;++i){
61         add_edge(new_Node[i][0],new_Node[i][1],0);add_edge(new_Node[i][1],new_Node[i][0],0);
62         add_edge(new_Node[i][2],new_Node[i][3],0);add_edge(new_Node[i][3],new_Node[i][2],0);
63
64         add_edge(new_Node[i][2],new_Node[i][0],1);add_edge(new_Node[i][0],new_Node[i][2],1);
65         add_edge(new_Node[i][2],new_Node[i][1],1);add_edge(new_Node[i][1],new_Node[i][2],1);
66
67         add_edge(new_Node[i][3],new_Node[i][0],1);add_edge(new_Node[i][0],new_Node[i][3],1);
68         add_edge(new_Node[i][3],new_Node[i][1],1);add_edge(new_Node[i][1],new_Node[i][3],1);
69     }
70     sort(p+1,p+n+1,cmp1);
71     for(int i=2;i<=n;++i)
72         if(p[i].x==p[i-1].x){
73             add_edge(new_Node[p[i-1].id][3],new_Node[p[i].id][2],0);
74             add_edge(new_Node[p[i].id][2],new_Node[p[i-1].id][3],0);
75         }
76     sort(p+1,p+n+1,cmp2);
77     for(int i=2;i<=n;++i)
78         if(p[i].y==p[i-1].y){
79             add_edge(new_Node[p[i-1].id][1],new_Node[p[i].id][0],0);
80             add_edge(new_Node[p[i].id][0],new_Node[p[i-1].id][1],0);
81         }
82     for(int i=0;i<=3;++i){
83         add_edge(S,new_Node[1][i],0);
84         add_edge(new_Node[2][i],T,0);
85     }
86     //cout<<1<<endl;
87     SPFA();
88     printf("%d\n",dis[T]>=Inf?-1:dis[T]);
89     return 0;
90 }

原文地址:https://www.cnblogs.com/LI-dox/p/11219516.html

时间: 2024-10-07 08:49:21

USACO 2016 December Contest Gold T3: Lasers and Mirrors的相关文章

USACO 2016 December Contest Gold T1: Moocast

题目大意 FJ的N头牛(1≤N≤1000)为了在他们之间传播信息, 想要组织一个"哞哞广播"系统. 奶牛们决定去用步话机装备自己而不是在很远的距离之外互相哞哞叫, 所以每一头奶牛都必须有一个步话机. 这些步话机都有一个限制传播半径, 但是奶牛们可以间接地通过中间奶牛传播信息, 所以并不是每头牛都必须直接向其他每一头奶牛连边. 奶牛们需要去决定多少钱花在步话机上, 如果他们花了$X, 那么他们都将会得到sqrt(x)距离的步话机. 所以, 两头牛之间的欧几里得距离平方最多是X. 请帮助奶

USACO 2017 December Contest Gold T1: A Pie for a Pie

题目大意 Bessie和Elsie各自烤了 N(1≤N≤10^5)个馅饼.Bessie 会这 2N 个馅饼打分,Elsie 也会.二者的打分均为一个 ≤1e9 的非负整数.由于她们口味不同,每个派的两个分数可能不同.她们想互赠礼物.开始时,Bessie 送给 Elsie 一个馅饼.她们收到礼物(对方做的馅饼)后都会回赠对方一个自己做的馅饼.她们选择回礼的方法相同.以 Elsie 为例,Elsie 根据自己的打分来选择回礼.回礼的分数至少要大于她收到的馅饼的分数,但两个馅饼的分数差不能大于 D(0

USACO 2017 December Contest Platinum T3: Greedy Gift Takers

题目大意 有 N(1≤N≤1e5)头牛按顺序排成一列,编号从 1 到 N,1 号牛在队头,N 号牛在队尾. 每次位于队头的牛 i 拿到一个礼物,然后插入到从队尾数ci?头牛之前的位置..举个栗子: 初始队列 1,2,3,4,5 c1?= 2,c2? = 3,则第一次操作后的序列为 2,3,1,4,5,第二次操作后的序列为 3,2,1,4,5.重复无限次操作,求最后有几头牛拿不到礼物. 题目分析 一上来有个显然的结论,若一个人得不到礼物那么原序列中在他后面的人肯定也得不到礼物,因为后面的人跳不到前

USACO 2016 US Open Contest Gold T3: 248

题目大意 给定一个1*n(2≤N≤248)的地图,在里面玩2048,每次可以合并相邻两个(数值范围1-40),问最大能合出多少.注意合并后的数值并非加倍而是+1,例如2与2合并后的数值为3. 题目分析 观察数据范围与题目,n<=248 并且 “每次可以合并相邻两个” ,不难想到要使用区间DP. 令 f[i][j] 表示区间 i~j 合并的最大值,则显然,转移为 (i < k < j )若f[i][k]==f[k+1][j] 则 f[i][j]=max(f[i][k]+1,f[i][j])

USACO 2007 December Contest, Silver Problem 2. Building Roads Kruskal最小生成树算法

PROBLEM: (ENGLISH VERSION) Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he can travel from any farm to any other farm via a sequence of roads; roads already connect some of the farms. Each of the N

USACO 2015 February Contest Gold T2: Censoring

题目大意 FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S.他有一个包含n个单词的列表,列表里的n个单词记为t1...tN.他希望从S中删除这些单词. FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词.他重复这个操作直到S中没有列表里的单词为止.注意删除一个单词后可能会导致S中出现另一个列表中的单词 FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的

USACO 2018 December Contest Platinum T2: Sort It Out

题目大意 FJ有 N(1≤N≤1e5 )头奶牛(分别用 1…N 编号)排成一行.FJ喜欢他的奶牛以升序排列,不幸的是现在她们的顺序被打乱了.在过去FJ曾经使用一些诸如“冒泡排序”的开创性的算法来使他的奶牛排好序,但今天他想偷个懒.取而代之,他会每次对着一头奶牛叫道“按顺序排好”.当一头奶牛被叫到的时候,她会确保自己在队伍中的顺序是正确的(从她的角度看来).当有一头紧接在她右边的奶牛的编号比她小,她们就交换位置.然后,当有一头紧接在她左边的奶牛的编号比她大,她们就交换位置.这样这头奶牛就完成了“按

USACO 2019 January Contest Platinum T3: Train Tracking 2

题目大意 每天特快列车都会经过农场.列车有N节车厢(1≤N≤10^5),每节车厢上有一个1到10^9之间的正整数编号:不同的车厢可能会有相同的编号. 平时,Bessie会观察驶过的列车,记录车厢的编号.但是今天雾实在太浓了,Bessie一个编号也看不见!幸运的是,她从城市里某个可靠的信息源获知了列车编号序列的所有滑动窗口中的最小值.具体地说,她得到了一个正整数K,以及N−K+1个正整数c1,…,cN+1−K,其中ci是车厢i,i+1,…,i+K−1之中编号的最小值. 帮助Bessie求出满足所有

USACO 2017 December Contest Platinum T2: Push a Box

题目大意 一个谷仓是一个N*M的矩形网格,有一些网格里有干草.Bessie站在其中一个格子内,还有一个格子里有一个大木箱.Bessie不能和大木箱在一个格子里,也不能和干草在一个格子里. 如果她不与干草一个格子,她就可以往自己旁边的四个方向(东西南北)移动,如果她想移动到有木箱的格子里,那个木箱就会被她推一格(只要木箱的那个方向还有空间),如果没有空间,那Bessie就不能移动了. 给你谷仓的布局(空格子,干草以及木箱位置)以及Bessie的出发位置和箱子要被推到的位置,请你帮忙计算Bessie