codeforces 514B. Han Solo and Lazer Gun 解题报告

题目链接:http://codeforces.com/problemset/problem/514/B

题目意思:给出双头枪的位置(x0, y0),以及 n 个突击队成员的坐标。双头枪射击一次,可以把它对住的方向(是直线,不是射线,因为是双头嘛)所有的人射杀掉。问将所有突击队成员消灭的最少射击数是多少。

    首先要清楚的是,双头枪可以瞄准的方向是无限的,所以通过枚举所有方向是不现实的!方向其实就是对应斜率,但是没有理由把函数求出然后将士兵的位置一个一个代入来做吧~~~所以呢,直接求 k 就可以了,k 表示枪(x0, y0)和任意士兵(x, y)的斜率。即 k =(y - y0)/ (x - x0)

    做的过程中要注意两个问题。 (1)k 有可能除不尽,所以要用 double 来保存。 (2)x - x0 有可能等于0,除数不能为 0 的!!但是也属于可行的一个方向,要单独判断,统计到答案中的其中一个解里。保存完所有 k 之后,去重后统计有多少个不同的 k 就是问题答案了。

  其实还有一个地方有点疑问,就是浮点数比较。本来打算用精度控制,毕竟比较的时候用 “ = ”多少是有一点误差的,但居然过了,可能数据比较弱吧,这个不太清楚,希望有能之士可以指点指点,不胜感激 [^__^]

    

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 1000 + 10;
 9 double k[maxn];
10 
11 int main()
12 {
13     #ifndef ONLINE_JUDGE
14         freopen("in.txt", "r", stdin);
15     #endif // ONLINE_JUDGE
16 
17     int n;
18     int x0, y0, x, y;
19     while (scanf("%d%d%d", &n, &x0, &y0) != EOF) {
20         int cnt = 0;
21         int f = 0;
22         int ans = 0;
23         for (int i = 0; i < n; i++) {
24             scanf("%d%d", &x, &y);
25             double tx = x - x0;
26             double ty = y - y0;
27             if (tx == 0 && !f) {    
28                 ans++;
29                 f = 1;
30             }
31             else if (tx != 0)
32                 k[cnt++] = ty / tx;     // 注意 cnt 不一定等于 n 
33         }
34 
35         sort(k, k+cnt);
36         for (int i = 0; i < cnt; i++) {
37             while (k[i] == k[i+1] && i < cnt)
38                 i++;
39             ans++;
40         }
41         printf("%d\n", ans);
42     }
43     return 0;
44 }

 

posted @ 2015-02-15 10:58  windysai  阅读(630)  评论(0编辑  收藏  举报