2012天津E题

给我们n个坐标点和一个距离d,表示车开m米就没油了。

然后要选几个点建立油站,使得能够从1出发遍历所有的点,然后回到1。  并且规定1这个点必须有油站,在第i个点建立油站的费用是 2^(i-1)

因为费用的特殊性质,如果最大的点能够不建立,那么肯定是不建的。 所以首先在所有的点建立油站,看是否可以遍历所有的点,然后依次从大到小枚举点,看是否可以不建立油站。

但是卡在如何判断是否能够遍历所有的点上。

首先判断,所有的油站距离最近的油站的距离不能超过d,  如果超过就不能到达,而且也不能通过没有油站的点中转

然后,不是油站的点距离最近的油站的距离不能超过d/2 ,这个很显然,如果超过d/2,那么从油站到达这个点,就没办法回去了。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <stack>
  7 #include <math.h>
  8 using namespace std;
  9 /*
 10  花费是2^(i-1) 这个很特殊
 11  如何高效得判断是否能经过所有的点然后回家?
 12  */
 13 const int INF = 1<<30;
 14 const int N = 128 + 10;
 15 struct Point
 16 {
 17     int x,y;
 18     double dist(const Point &rhs)
 19     {
 20         return sqrt( (x-rhs.x)*(x-rhs.x)+(y-rhs.y)*(y-rhs.y) );
 21     }
 22 }a[N];
 23 int n,d;
 24 int dist[N][N];
 25 int sta[N];
 26 bool vis[N];
 27 int cnt1,cnt2;
 28 bool bfs()
 29 {
 30     memset(vis,0,sizeof(vis));
 31     int tmp = 0;
 32     for(int i=1;i<=n;++i)
 33         tmp += sta[i];
 34     cnt1 = 1;
 35     cnt2 = 0;
 36     vis[1] = true;
 37     queue<int> q;
 38     q.push(1);
 39     while(!q.empty())
 40     {
 41         int u = q.front();q.pop();
 42         for(int i=2;i<=n;++i)
 43         {
 44             if(!sta[i]) continue;
 45             if(!vis[i] && dist[u][i]<=d)
 46             {
 47                 q.push(i);
 48                 cnt1++;
 49                 vis[i] = true;
 50             }
 51         }
 52     }
 53     for(int i=1;i<=n;++i)
 54         if(sta[i]) q.push(i);
 55     while(!q.empty())
 56     {
 57         int u = q.front(); q.pop();
 58         for(int i=2;i<=n;++i)
 59         {
 60             if(sta[i]) continue;
 61             if(!vis[i] && dist[u][i]*2<=d)
 62             {
 63                 vis[i] = true;
 64                 cnt2++;
 65             }
 66         }
 67     }
 68     if(cnt1==tmp && cnt2==n-tmp) return true;
 69
 70     return false;
 71 }
 72 int main()
 73 {
 74     //freopen("d:/in.txt","r",stdin);
 75     while(scanf("%d%d",&n,&d)!=EOF)
 76     {
 77         for(int i=1;i<=n;++i)
 78         {
 79             scanf("%d%d",&a[i].x,&a[i].y);
 80             sta[i] = true;
 81         }
 82         for(int i=1;i<=n;++i)
 83         {
 84             for(int j=1;j<=n;++j)
 85                 dist[i][j] = dist[j][i] = (int)ceil(a[i].dist(a[j]));
 86         }
 87         if(bfs())
 88         {
 89
 90             for(int i=n;i>=2;--i)
 91             {
 92                 sta[i] = false;
 93                 if(!bfs())
 94                     sta[i] = true;
 95             }
 96             while(sta[n]==0) n--;
 97             for(int i=n;i>=1;--i)
 98                 printf("%d",sta[i]);
 99             puts("");
100         }
101         else
102             puts("-1");
103     }
104     return 0;
105 }
时间: 2024-11-04 02:18:28

2012天津E题的相关文章

USACO翻译:USACO 2012 JAN三题(1)

USACO 2012 JAN(题目一) 一.题目概览 中文题目名称 礼物 配送路线 游戏组合技 英文题目名称 gifts delivery combos 可执行文件名 gifts delivery combos 输入文件名 gifts.in delivery.in combos.in 输出文件名 gifts.out delivery.out combos.out 每个测试点时限 1秒 1秒 1秒 测试点数目 10 10 10 每个测试点分值 10 10 10 比较方式 全文比较 全文比较 全文比

USACO翻译:USACO 2012 JAN三题(2)

USACO 2012 JAN(题目二) 一.题目概览 中文题目名称 叠干草 分干草 奶牛跑步 英文题目名称 stacking baleshare cowrun 可执行文件名 stacking baleshare cowrun 输入文件名 stacking.in baleshare.in cowrun.in 输出文件名 stacking.out baleshare.out cowrun.out 每个测试点时限 1秒 1秒 1秒 测试点数目 10 10 10 每个测试点分值 10 10 10 比较方

【2012天津区域赛】部分题解 hdu4431—4441

1001: 题意:给你13张麻将牌,问可以胡哪些张 思路: 枚举可能接到的牌,然后dfs判断能否胡 1002: 题意: 已知n,m 求 n的所有约数在m进制下的平方和 做法:队长用java高精度写的 代码: import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.PrintWriter; import java.io.ObjectInputStream.GetField; im

USACO翻译:USACO 2012 JAN三题(3)

USACO 2012JAN(题目三) 一.题目概览 中文题目名称 放牧 登山 奶牛排队 英文题目名称 grazing climb lineup 可执行文件名 grazing climb lineup 输入文件名 grazing.in climb.in lineup.in 输出文件名 grazing.out climb.out lineup.out 每个测试点时限 1秒 1秒 1秒 测试点数目 10 10 10 每个测试点分值 10 10 10 比较方式 全文比较 全文比较 全文比较 二.运行内存

2012长春站B题 zoj 3656 并查集

好像大神都用的是2-sat,其实我也有想过.因为我碰到过的判断yes or no的题目就那么几种(2-sat,并查集,搜索,博弈),(因为本人比较水,所以就碰到了这几种,看来以后还是要多做体检积累经验:)),但是比赛的时候还是用了并查集,下面是我的并查集解法: 把b[][]数组上的每个位拆开成两个点i和i',(不超过32位),另外新加两个点0和1,如果确定某点i对应的是0,则i与0点合并,i'点与1点合并:如果确定某点i对应的是1,则i与1合并,i'与0合并:如果确定两点i和j对应的位是相反的数

hdu 4278 2012天津赛区网络赛 数学 *

8进制转为10进制 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f

HDU4287-STL模拟水题

一场2012天津网络预选赛的题,签到题. 但是还是写了三四十分钟,C++和STL太不熟悉了,总是编译错误不知道怎么解决. 一开始用的Char [] 后来改成了string,STL和string搭配起来才好用啊. 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <ctype.h> 5 #include <cstdlib> 6 #include

HDU 4438 Hunters 区域赛水题

本文转载于 http://blog.csdn.net/major_zhang/article/details/52197538 2012天津区域赛最水之题: 题意容易读懂,然后就是分情况求出A得分的数学期望,所谓数学期望就是在该概率下的平均得分. 现在就是两种方案,Alice要根据输入给出的数据情况选出最优方案,也就是先选老虎,还是狼. 1.A先选老虎: a.B也先选老虎,则得分为Q(P*X+P*Y); //打完老虎还要打狼 b.B选狼,则两人可以直接获得猎物,则得分为(1-Q)*X 所以1方案

软件评測师真题解答与分析8

2009上半年真题11: 程序猿甲与同事乙在乙家探讨甲最近编写的程序,甲表示对该程序极不惬意.说要弃之重写,并将程序手稿扔到乙家垃圾桶. 后来乙将甲这一程序稍加改动,并署乙名发表.下面说法正确的是(). A.乙的行为侵犯了甲的软件著作权 B.乙的行为没有侵犯甲的著作权,由于甲已经程序手稿丢弃 C.乙的行为没有侵犯甲的著作权.由于乙已经程序改动 D.甲没有发表该程序并弃之,而乙将程序改动后发表,故乙应享有著作权 分析解答:本题考查知识产权中关于软件著作权方面的知识. 著作权因作品的完毕而自己主动产