CodeForcesGym 100524A Astronomy Problem

Astronomy Problem

Time Limit: 8000ms
Memory Limit: 524288KB
This problem will be judged on CodeForcesGym. Original ID: 100524A
64-bit integer IO format: %I64d      Java class name: (Any)
 
解题:暴力搞
$设两个点的坐标分别为(x_1,y_1),(x_2,y_2)且有x_1^2+y_1^2 = a^2,x_2^2+y_2^2=b^2,那么有(x_1-x_2)^2+(y_1-y_2)^2=c^2。$
$于是推出一个错误的公式,a^2+b^2-c^2=2\times (x_1\times x_2+y_1\times y_2),初略的想法是:等式右边是固定的,所以可以根据这个进行排序,左边是不定的$
$可以用左边找右边,可是,可是,WA第7组数据. 因为,你算多了,而且这个等式本身就不对$
$但是,但是,这个错误的等式可以为我们省出不少的点对,只要不满足这个等式的点对,一定不是符合条件的,但是满足这个等式,也有可能不符合条件$
$所以只会找出这些点对,进行一一检验即可$
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 3010;
 5 struct Point{
 6     LL val,a,b,c;
 7     Point(LL val = 0,LL a = 0,LL b = 0,LL c = 0){
 8         this->val = val;
 9         this->a = a;
10         this->b = b;
11         this->c = c;
12     }
13     bool operator<(const Point &rhs)const{
14         return val < rhs.val;
15     }
16 }P[maxn*maxn];
17 int x[maxn],y[maxn],n,q,tot;
18 LL calc(int a,int b){
19     LL tmp = (LL)(x[a] - x[b])*(x[a] - x[b]);
20     return tmp + (LL)(y[a] - y[b])*(y[a] - y[b]);
21 }
22 int main(){
23     freopen("astronomy.in","r",stdin);
24     freopen("astronomy.out","w",stdout);
25     while(~scanf("%d",&n)){
26         if(!n) break;
27         tot = 0;
28         for(int i = 1; i <= n; ++i){
29             scanf("%d%d",x + i,y + i);
30             for(int j = 1; j < i; ++j){
31                 LL tmp = ((LL)x[i]*x[j] + (LL)y[i]*y[j])<<1;
32                 P[tot++] = Point(tmp,calc(j,0),calc(i,0),calc(i,j));
33             }
34         }
35         sort(P,P + tot);
36         scanf("%d",&q);
37         while(q--){
38             LL a,b,c;
39             scanf("%I64d%I64d%I64d",&a,&b,&c);
40             LL tmp = a - c + b;
41             if(n == 1 || tmp&1){
42                 puts("0");
43                 continue;
44             }
45             int low = lower_bound(P,P + tot,Point(tmp,0,0,0)) - P,ret = 0;
46             while(low < tot && P[low].val == tmp){
47                 if(P[low].a == a && P[low].b == b || P[low].a == b && P[low].b == a) ++ret;
48                 ++low;
49             }
50             printf("%d\n",ret);
51         }
52     }
53     return 0;
54 }
55 /*
56 4
57 0 2
58 2 0
59 4 0
60 0 -4
61 2
62 4 16 20
63 16 4 20
64 */
View Code

 

然后学习了下某位大神的写法

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 3010;
 5 unordered_map<LL,vector<int>>ump;
 6 unordered_map<LL,int>ret;
 7 map<pair<LL,LL>,vector<pair<LL,int>>>Q;
 8 struct Point {
 9     LL x,y;
10     Point(LL x = 0,LL y = 0) {
11         this->x = x;
12         this->y = y;
13     }
14 } p[maxn];
15 LL calc(const Point &a,const Point &b) {
16     LL tmp = (a.x - b.x)*(a.x - b.x);
17     return tmp + (a.y - b.y)*(a.y - b.y);
18 }
19 set<LL>st;
20 int ans[maxn];
21 int main() {
22 #define NAME "astronomy"
23     freopen(NAME".in","r",stdin);
24     freopen(NAME".out","w",stdout);
25     int n,q;
26     while(~scanf("%d",&n)) {
27         if(!n) break;
28         ump.clear();
29         Q.clear();
30         memset(ans,0,sizeof ans);
31         for(int i = 1; i <= n; ++i) {
32             scanf("%I64d%I64d",&p[i].x,&p[i].y);
33             ump[p[i].x*p[i].x+p[i].y*p[i].y].push_back(i);
34         }
35         scanf("%d",&q);
36         for(int i = 0; i < q; ++i){
37             LL a,b,c;
38             scanf("%I64d%I64d%I64d",&a,&b,&c);
39             Q[make_pair(a,b)].push_back(make_pair(c,i));
40         }
41         for(auto &it:Q){
42             st.clear();
43             for(auto &it2:it.second) st.insert(it2.first);
44             LL a = it.first.first,b = it.first.second;
45             ret.clear();
46             for(auto &x:ump[a]){
47                 for(auto &y:ump[b]){
48                     if(a == b && x < y) continue;
49                     if(x == y) continue;
50                     LL d = calc(p[x],p[y]);
51                     if(st.find(d) == st.end()) continue;
52                     ret[d]++;
53                 }
54             }
55             for(auto &v:it.second)
56                 ans[v.second] = ret[v.first];
57         }
58         for(int i = 0; i < q; ++i)
59             printf("%d\n",ans[i]);
60     }
61     return 0;
62 }
63 /*
64 4
65 0 2
66 2 0
67 4 0
68 0 -4
69 2
70 4 16 20
71 16 4 20
72 */
View Code

 

posted @ 2015-10-07 20:29  狂徒归来  阅读(270)  评论(0编辑  收藏  举报