hihoCoder挑战赛14 A,B,C题解

转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

 

题目1 : 不等式

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

给定n个关于X的不等式,问最多有多少个成立。

每个不等式为如下的形式之一:

X < C

X <= C

X = C

X > C

X >= C

输入

第一行一个整数n。

以下n行,每行一个不等式。

数据范围:

1<=N<=50,0<=C<=1000

输出

一行一个整数,表示最多可以同时成立的不等式个数。

样例输入
4
X = 1
X = 2
X = 3
X > 0
样例输出
2

枚举所有值,每隔0.5一个,这样就能取到所有情况了。少了小数部分,WA了两下才发现。。。真是惨

  1 /**
  2  * code generated by JHelper
  3  * More info: https://github.com/AlexeyDmitriev/JHelper
  4  * @author xyiyy @https://github.com/xyiyy
  5  */
  6 
  7 #include <iostream>
  8 #include <fstream>
  9 
 10 //#####################
 11 //Author:fraud
 12 //Blog: http://www.cnblogs.com/fraud/
 13 //#####################
 14 //#pragma comment(linker, "/STACK:102400000,102400000")
 15 #include <iostream>
 16 #include <sstream>
 17 #include <ios>
 18 #include <iomanip>
 19 #include <functional>
 20 #include <algorithm>
 21 #include <vector>
 22 #include <string>
 23 #include <list>
 24 #include <queue>
 25 #include <deque>
 26 #include <stack>
 27 #include <set>
 28 #include <map>
 29 #include <cstdio>
 30 #include <cstdlib>
 31 #include <cmath>
 32 #include <cstring>
 33 #include <climits>
 34 #include <cctype>
 35 
 36 using namespace std;
 37 #define XINF INT_MAX
 38 #define INF 0x3FFFFFFF
 39 #define mp(X, Y) make_pair(X,Y)
 40 #define pb(X) push_back(X)
 41 #define rep(X, N) for(int X=0;X<N;X++)
 42 #define rep2(X, L, R) for(int X=L;X<=R;X++)
 43 #define dep(X, R, L) for(int X=R;X>=L;X--)
 44 #define clr(A, X) memset(A,X,sizeof(A))
 45 #define IT iterator
 46 #define ALL(X) (X).begin(),(X).end()
 47 #define PQ std::priority_queue
 48 typedef long long ll;
 49 typedef unsigned long long ull;
 50 typedef pair<int, int> PII;
 51 typedef vector<PII> VII;
 52 typedef vector<int> VI;
 53 
 54 int getTheAnswer() {
 55     return 42;
 56 }
 57 
 58 char a[110];
 59 string str[110];
 60 double num[110];
 61 
 62 class TaskA {
 63 public:
 64     void solve(std::istream &in, std::ostream &out) {
 65         int n;
 66         while (in >> n) {
 67             rep(i, n)
 68                 in >> a[i] >> str[i] >> num[i];
 69             int ans = 0;
 70             for (double i = -1.5; i < 1010; i += 1.0) {
 71                 int m = 0;
 72                 rep(j, n) {
 73                     if (gao(i, j))m++;
 74                 }
 75                 ans = max(ans, m);
 76             }
 77             rep2(i, -10, 1010) {
 78                 int m = 0;
 79                 rep(j, n) {
 80                     if (gao(i, j))m++;
 81                 }
 82                 ans = max(ans, m);
 83             }
 84             out << ans << endl;
 85 
 86         }
 87     }
 88 
 89     bool gao(double x, int i) {
 90         if (str[i] == "<") {
 91             return x < num[i];
 92         } else if (str[i] == "<=") {
 93             return x <= num[i];
 94         } else if (str[i] == "=") {
 95             return x == num[i];
 96         } else if (str[i] == ">") {
 97             return x > num[i];
 98         } else if (str[i] == ">=") {
 99             return x >= num[i];
100         }
101     }
102 };
103 
104 int main() {
105     std::ios::sync_with_stdio(false);
106     std::cin.tie(0);
107     TaskA solver;
108     std::istream &in(std::cin);
109     std::ostream &out(std::cout);
110     solver.solve(in, out);
111     return 0;
112 }
代码君

题目2 : 赛车

时间限制:20000ms
单点时限:1000ms
内存限制:256MB

描述

幻想乡有一个赛车场。赛车场里有N个地点。同时地点之间还有单向的道路存在。

这些道路使得赛车场形成了一个外向树的结构。也就是说,道路将这N个地点连成了一个有根树。并且所有的边都是从父亲指向孩子的。

由于幽香喜欢刺激,每次她去赛车场都会从根节点出发,选择最长的一条路径来玩。

但是现在幽香感觉最长的路径还是太短了,她打算在赛车场里新建一条道路使得新的最长路径最长。

同时,如果道路形成了一个环,那么可能会出现交通事故,所以幽香新建的道路不能导致环的出现。

你能帮幽香算出新建一条道路后的最长路径吗?幽香知道根节点一定是1号点。

输入

一行一个数N,表示地点的数量。

接下来N-1行,每行两个数a和b,表示从点a到点b有一条单向路径。所有点从1到n标号。

数据范围:

n<=100000。

输出

一行表示新建一条边后的最长路径。

样例输入
5
1 2
2 3
1 4
4 5
样例输出
4

树形DP裸题,先dfs处理一下,然后枚举所有点,求出从根节点出发到这个点的路径长度,以及这个点往下的最长路以及次长路即可。

  1 /**
  2  * code generated by JHelper
  3  * More info: https://github.com/AlexeyDmitriev/JHelper
  4  * @author xyiyy @https://github.com/xyiyy
  5  */
  6 
  7 #include <iostream>
  8 #include <fstream>
  9 
 10 //#####################
 11 //Author:fraud
 12 //Blog: http://www.cnblogs.com/fraud/
 13 //#####################
 14 //#pragma comment(linker, "/STACK:102400000,102400000")
 15 #include <iostream>
 16 #include <sstream>
 17 #include <ios>
 18 #include <iomanip>
 19 #include <functional>
 20 #include <algorithm>
 21 #include <vector>
 22 #include <string>
 23 #include <list>
 24 #include <queue>
 25 #include <deque>
 26 #include <stack>
 27 #include <set>
 28 #include <map>
 29 #include <cstdio>
 30 #include <cstdlib>
 31 #include <cmath>
 32 #include <cstring>
 33 #include <climits>
 34 #include <cctype>
 35 
 36 using namespace std;
 37 #define XINF INT_MAX
 38 #define INF 0x3FFFFFFF
 39 #define mp(X, Y) make_pair(X,Y)
 40 #define pb(X) push_back(X)
 41 #define rep(X, N) for(int X=0;X<N;X++)
 42 #define rep2(X, L, R) for(int X=L;X<=R;X++)
 43 #define dep(X, R, L) for(int X=R;X>=L;X--)
 44 #define clr(A, X) memset(A,X,sizeof(A))
 45 #define IT iterator
 46 #define ALL(X) (X).begin(),(X).end()
 47 #define PQ std::priority_queue
 48 typedef long long ll;
 49 typedef unsigned long long ull;
 50 typedef pair<int, int> PII;
 51 typedef vector<PII> VII;
 52 typedef vector<int> VI;
 53 
 54 int getTheAnswer() {
 55     return 42;
 56 }
 57 
 58 vector<int> G[100010];
 59 int dp[100010][2];
 60 int pre[100010][2];
 61 int dep[100010];
 62 int ans;
 63 
 64 class TaskB {
 65 public:
 66     void solve() {
 67         int n;
 68         while (scanf("%d",&n)!=EOF) {
 69             rep(i, n)G[i].clear();
 70             int u, v;
 71             rep(i, n - 1) {
 72                 scanf("%d%d",&u,&v);//in >> u >> v;
 73                 u--;
 74                 v--;
 75                 G[u].pb(v);
 76             }
 77             dep[0] = 0;
 78             dfs(0, -1);
 79             ans = 0;
 80             dfs2(0, -1);
 81             printf("%d\n",ans);//out << ans << endl;
 82         }
 83     }
 84 
 85     void dfs(int u, int fa) {
 86         dp[u][0] = dp[u][1] = 0;
 87         pre[u][0] = pre[u][1] = -1;
 88         int sz = G[u].size();
 89         rep(i, sz) {
 90             int v = G[u][i];
 91             dep[v] = dep[u] + 1;
 92             dfs(v, u);
 93             if (dp[v][0] + 1 > dp[u][1]) {
 94                 dp[u][1] = dp[v][0] + 1;
 95                 pre[u][1] = v;
 96                 if (dp[u][1] > dp[u][0]) {
 97                     swap(dp[u][1], dp[u][0]);
 98                     swap(pre[u][1], pre[u][0]);
 99                 }
100             }
101         }
102     }
103 
104     void dfs2(int u, int fa) {
105         int sz = G[u].size();
106         rep(i, sz) {
107             int v = G[u][i];
108             ans = max(ans, dp[u][1] + dep[u] + dp[u][0]);
109             dfs2(v, u);
110         }
111     }
112 };
113 
114 int main() {
115     TaskB solver;
116     solver.solve();
117     return 0;
118 }
代码君

题目3 : 向日葵

时间限制:30000ms
单点时限:1500ms
内存限制:256MB

描述

幽香打算种一些向日葵,让自己的太阳花田更加的漂亮。

现在太阳花田上什么植物都没有。幽香搞到了一些向日葵的种子。不过幽香觉得如果直接种的话太无趣了,

她打算采取一种比较有趣的种法。

她在太阳花田上选择了n对点,分别为(a1,b1),(a2,b2),...,(an,bn)。然后对于每一对点(ai,bi),她会以一半的概率在ai种一个向日葵,一半的概率在bi种一个向日葵。

种完向日葵以后,幽香需要将这些向日葵围起来建成花园。防止被其它小妖精踩踏。花园可以看成就是这些种了的向日葵的凸包。那么幽香想知道花园的期望大小是多少呢?

输入

第一行n,表示点对的个数。

接下来n行,每行4个数,第i行前两个数为ai的x,y坐标,后两个数为bi的x,y坐标。

数据范围:

n<=1000。

所有坐标都是绝对值小于1e9的整数。

输入中的2n个点不存在3点共线,或者2点重合的情况。

输出

一行答案。相对误差在1e-6以内就算正确。

样例输入
10
703 548 811 701
978 368 435 32
270 667 550 68
326 486 217 486
116 344 361 418
591 563 38 373
548 210 94 800
978 1000 169 278
362 32 899 331
401 339 399 334
样例输出
407253.2333984375

比赛的时候一直没想通每条边在凸包出现的概率怎么算。

因为边的概率其实就是有向三角形的概率,而所有有向三角形面积的和就是凸包的面积。

先枚举所有边,然后再枚举所有点,对于每个点, 看在其左边和右边的的可能性,那么其概率就是两个点中叉积小于0的概率,因为小于0的点才是在凸包内的,这样枚举的那条边才会对面积做出贡献。

  1 /**
  2  * code generated by JHelper
  3  * More info: https://github.com/AlexeyDmitriev/JHelper
  4  * @author xyiyy @https://github.com/xyiyy
  5  */
  6 
  7 #include <iostream>
  8 #include <fstream>
  9 
 10 //#####################
 11 //Author:fraud
 12 //Blog: http://www.cnblogs.com/fraud/
 13 //#####################
 14 //#pragma comment(linker, "/STACK:102400000,102400000")
 15 #include <iostream>
 16 #include <sstream>
 17 #include <ios>
 18 #include <iomanip>
 19 #include <functional>
 20 #include <algorithm>
 21 #include <vector>
 22 #include <string>
 23 #include <list>
 24 #include <queue>
 25 #include <deque>
 26 #include <stack>
 27 #include <set>
 28 #include <map>
 29 #include <cstdio>
 30 #include <cstdlib>
 31 #include <cmath>
 32 #include <cstring>
 33 #include <climits>
 34 #include <cctype>
 35 
 36 using namespace std;
 37 #define XINF INT_MAX
 38 #define INF 0x3FFFFFFF
 39 #define mp(X, Y) make_pair(X,Y)
 40 #define pb(X) push_back(X)
 41 #define rep(X, N) for(int X=0;X<N;X++)
 42 #define rep2(X, L, R) for(int X=L;X<=R;X++)
 43 #define dep(X, R, L) for(int X=R;X>=L;X--)
 44 #define clr(A, X) memset(A,X,sizeof(A))
 45 #define IT iterator
 46 #define ALL(X) (X).begin(),(X).end()
 47 #define PQ std::priority_queue
 48 typedef long long ll;
 49 typedef unsigned long long ull;
 50 typedef pair<int, int> PII;
 51 typedef vector<PII> VII;
 52 typedef vector<int> VI;
 53 
 54 int getTheAnswer() {
 55     return 42;
 56 }
 57 //
 58 // Created by xyiyy on 2015/8/10.
 59 //
 60 
 61 #ifndef ICPC_P_HPP
 62 #define ICPC_P_HPP
 63 
 64 const double EPS = 1e-10;
 65 
 66 int sig(double x) {
 67     if (fabs(x) < EPS)return 0;
 68     return x < 0 ? -1 : 1;
 69 }
 70 
 71 double add(double a, double b) {
 72     if (fabs(a + b) < EPS * (fabs(a) + fabs(b)))return 0;
 73     return a + b;
 74 }
 75 
 76 class P {
 77 public:
 78     double x, y;
 79 
 80     P() { }
 81 
 82     P(double x, double y) : x(x), y(y) { }
 83 
 84     P  operator+(const P &p) {
 85         return P(add(x, p.x), add(y, p.y));
 86     }
 87 
 88     P operator-(const P &p) {
 89         return P(add(x, -p.x), add(y, -p.y));
 90     }
 91 
 92     P operator*(const double &d) {
 93         return P(x * d, y * d);
 94     }
 95 
 96     P operator/(const double &d) {
 97         return P(x / d, y / d);
 98     }
 99 
100     double Dot(P p) {
101         return x * p.x + y * p.y;
102     }
103 
104     double dot(P p) {
105         return add(x * p.x, y * p.y);
106     }
107 
108     double Det(P p) {
109         return x * p.y - y * p.x;
110     }
111 
112     double det(P p) {
113         return add(x * p.y, -y * p.x);
114     }
115 
116 
117     double abs() {
118         return sqrt(abs2());
119     }
120 
121     double abs2() {
122         return dot(*this);
123     }
124 
125     //绕原点旋转角度B(弧度值)产生新的点
126     P rot(double rad) {
127         return P(add(x * cos(rad), -y * sin(rad)), add(x * sin(rad), y * cos(rad)));
128     }
129 
130     P rot90() {
131         return P(-y, x);
132     }
133 
134     bool equals(P p) {
135         return compareTo(p) == 0;
136     }
137 
138     int compareTo(P p) {
139         int b = sig(x - p.x);
140         if (b != 0)return b;
141         return sig(y - p.y);
142     }
143 
144 };
145 
146 
147 //判断点是否在线段上
148 bool on_seg(P p1, P p2, P q) {
149     return (p1 - q).det(p2 - q) == 0 && (p1 - q).dot(p2 - q) <= 0;
150 }
151 
152 //求两条线段的交点
153 P intersection(P p1, P p2, P q1, P q2) {
154     return p1 + (p2 - p1) * ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1));
155 }
156 
157 //线段相交判定
158 bool crsSS(P p1, P p2, P q1, P q2) {
159     if (max(p1.x, p2.x) + EPS < min(q1.x, q2.x))return false;
160     if (max(q1.x, q2.x) + EPS < min(p1.x, p2.x))return false;
161     if (max(p1.y, p2.y) + EPS < min(q1.y, q2.y))return false;
162     if (max(q1.y, q2.y) + EPS < min(p1.y, p2.y))return false;
163     /*(if((p1 - p2).det(q1 - q2) == 0){
164         return (on_seg(p1,p2,q1) || on_seg(p1,p2,q2) || on_seg(q1,q2,p1) || on_seg(q1,q2,p2));
165     }else{
166         P r = intersection(p1,p2,q1,q2);
167         return on_seg(p1,p2,r) && on_seg(q1,q2,r);
168 
169     }*/
170     return (p2 - p1).det(q1 - p1) * (p2 - p1).det(q2 - p1) <= 0
171            && (q2 - q1).det(p1 - q1) * (q2 - q1).det(p2 - q1) <= 0;
172 }
173 
174 //直线和线段相交判断
175 bool crsLS(P l1, P l2, P s1, P s2) {
176     return (s1 - l2).det(l1 - l2) * (s2 - l2).det(l1 - l2) <= 0;
177 }
178 
179 //直线相交判断
180 //返回-1表示重合,0表示平行,1表示相交
181 int crsLL(P p1, P p2, P q1, P q2) {
182     if (sig((p1 - p2).det(q1 - q2)) != 0)return 1;
183     if (sig((p1 - q2).det(q1 - p2)) != 0)return 0;
184     return -1;
185 }
186 
187 //直线和直线的交点
188 /*P isLL(P p1,P p2,P q1,P q2){
189     double d = (q2 - q1).det(p2 - p1);
190     if(sig(d)==0)return NULL;
191     return intersection(p1,p2,q1,q2);
192 }*/
193 
194 //点到直线的垂足
195 P proj(P p1, P p2, P q) {
196     return p1 + ((p2 - p1) * ((p2 - p1).dot(q - p1) / (p2 - p1).abs2()));
197 }
198 
199 //直线到点的距离
200 double disLP(P p1, P p2, P q) {
201     return fabs((p2 - p1).det(q - p1)) / (p2 - p1).abs();
202 }
203 
204 
205 //线段到点的距离
206 double disSP(P p1, P p2, P q) {
207     if ((p2 - p1).dot(q - p1) <= 0)return (q - p1).abs();
208     if ((p1 - p2).dot(q - p2) <= 0)return (q - p2).abs();
209     return disLP(p1, p2, q);
210 }
211 
212 //圆和线段相交的判定
213 bool crsCS(P c, double r, P p1, P p2) {
214     return disSP(p1, p2, c) < r + EPS && (r < (c - p1).abs() + EPS || r < (c - p2).abs() + EPS);
215 }
216 
217 //圆与圆相交的判定
218 bool crsCC(P c1, double r1, P c2, double r2) {
219     double dis = (c1 - c2).abs();
220     return dis < r1 + r2 + EPS && fabs(r1 - r2) < dis + EPS;
221 }
222 
223 //四点共圆判定
224 /*bool onC(P p1,P p2,P p3,P p4){
225     P c = CCenter(p1,p2,p3);
226     if(c == NULL) return false;
227     return add((c - p1).abs2(), -(c - p4).abs2()) == 0;
228 }*/
229 
230 //三点共圆的圆心
231 /*P CCenter(P p1,P p2,P p3){
232     //if(disLP(p1, p2, p3) < EPS)return NULL;//三点共线
233     P q1 = (p1 + p2) * 0.5;
234     P q2 = q1 + ((p1 - p2).rot90());
235     P s1 = (p3 + p2) * 0.5;
236     P s2 = s1 + ((p3 - p2).rot90());
237     return isLL(q1,q2,s1,s2);
238 }*/
239 
240 //求两圆的极角 以p为中心
241 double polarangle(P p, P q) {
242     return atan2(q.y - p.y, q.x - p.x);
243 }
244 
245 
246 bool cmp_x(const P &p, const P &q) {
247     if (p.x != q.x) return p.x < q.x;
248     return p.y < q.y;
249 }
250 
251 vector<P> qs;
252 
253 void convex_hull(P *ps, int n) {
254     sort(ps, ps + n, cmp_x);
255     int k = 0;
256     qs.resize(2 * n);
257     for (int i = 0; i < n; qs[k++] = ps[i++]) {
258         while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) < EPS)k--;
259     }
260     for (int i = n - 2, t = k; i >= 0; qs[k++] = ps[i--]) {
261         while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) < EPS)k--;
262     }
263     qs.resize(k - 1);
264 }
265 
266 //求凸包的直径
267 double convexDiameter() {
268     int qsz = qs.size();
269     if (qsz == 1)return 0;
270     if (qsz == 2) {
271         return (qs[0] - qs[1]).abs();
272     }
273     int i = 0, j = 0;
274     rep(k, qsz) {
275         if (!cmp_x(qs[i], qs[k]))i = k;
276         if (cmp_x(qs[j], qs[k])) j = k;
277     }
278     double res = 0;
279     int si = i, sj = j;
280     while (i != sj || j != si) {
281         res = max(res, (qs[i] - qs[j]).abs());
282         if ((qs[(i + 1) % qsz] - qs[i]).det(qs[(j + 1) % qsz] - qs[j]) < 0) i = (i + 1) % qsz;
283         else j = (j + 1) % qsz;
284     }
285     return res;
286 }
287 
288 
289 #endif //ICPC_P_HPP
290 
291 P p[1010][2];
292 
293 class TaskC {
294 public:
295     void solve(std::istream &in, std::ostream &out) {
296         int n;
297         in >> n;
298         rep(i, n)
299             rep(j, 2)in >> p[i][j].x >> p[i][j].y;
300         double ans = 0;
301         rep(i, n)
302             rep(l1, 2) {
303                 P p1 = p[i][l1];
304                 rep(j, n) {
305                     if (i == j)continue;
306                     rep(l2, 2) {
307                         P p2 = p[j][l2];
308                         double sum = p1.Det(p2) * 0.125;
309                         p2 = p2 - p1;
310                         rep(k, n) {
311                             if (i == k || j == k)continue;
312                             if (sig(sum) == 0)break;
313                             int num = 0;
314                             rep(l3, 2) {
315                                 if (p2.Det(p[k][l3] - p1) > 0);
316                                 else num++;
317                             }
318                             sum *= num/2.0;
319                         }
320                         ans += sum;
321                     }
322                 }
323             }
324         out << fixed << setprecision(10) << fabs(ans) << endl;
325     }
326 };
327 
328 int main() {
329     std::ios::sync_with_stdio(false);
330     std::cin.tie(0);
331     TaskC solver;
332     std::istream &in(std::cin);
333     std::ostream &out(std::cout);
334     solver.solve(in, out);
335     return 0;
336 }
代码君

当然,对于这题你也可以对于每个点先求出所有点的极角,排个序然后来做。这样就可以从O(n^3)变成O(n^2logn)了

还剩下D题还是不会做,待以后再补

 

posted on 2015-08-30 23:25  xyiyy  阅读(548)  评论(0编辑  收藏  举报

导航