NC204780. 二维动点
描述
输入描述
第一行为两个数n,q
接下来n行,每行两个数,表示一个点的坐标
接下来q行,每行两个数,表示询问一个目标点
输出描述
共q行,每行一个整数,表示到达目标点所需要的的最少移动次数,无解输出-1
示例1
输入:
2 3 1 2 2 1 3 3 2 4 2 2
输出:
3 1 2
C++14(g++5.4) 解法, 执行用时: 385ms, 内存消耗: 14604K, 提交时间: 2020-06-12 19:29:45
#include<bits/stdc++.h> using namespace std; #define int long long #define mp make_pair #define y1 ____y1 const int N=100005; int n,m,x,y,cnt,tot; map<pair<int,int> ,int> Map; int a[N],b[N]; inline int pd(int x1,int y1,int x2,int y2){ return x1*y2-x2*y1!=0; } signed main(){ scanf("%lld%lld",&n,&m); for (int i=1;i<=n;i++){ scanf("%lld%lld",&x,&y); if (!x&&!y)continue; int d=__gcd(x,y); x/=d;y/=d; cnt+=!Map[mp(x,y)]; Map[mp(x,y)]=1; a[++tot]=x*d;b[tot]=y*d; } while (m--){ scanf("%lld%lld",&x,&y); if (!x&&!y){ puts("0"); continue; } int d=__gcd(x,y); x/=d;y/=d; if (Map[mp(x,y)])puts("1"); else if (cnt<=1)puts("-1"); else if (tot>2)puts("2"); else { x*=d;y*=d; if (pd(a[1],b[1],x-a[2],y-b[2]))puts("2"); else if (pd(a[2],b[2],x-a[1],y-b[1]))puts("2"); else puts("3"); } } }
C++11(clang++ 3.9) 解法, 执行用时: 584ms, 内存消耗: 28776K, 提交时间: 2020-06-13 10:20:29
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e5+5; map<int,map<int,int>> mp; LL a[3],b[3]; int main(){ int n,q,len=0; cin>>n>>q; while(n--){ int x,y,z; cin>>x>>y; z=__gcd(x,y); if(!x&&!y||mp[x/z][y/z])continue; mp[x/z][y/z]=1; if(len<2)a[len]=x,b[len]=y; len++; } while(q--){ int x,y,z; cin>>x>>y; z=__gcd(x,y); if(!x&&!y){cout<<0<<endl;continue;} if(mp[x/z][y/z]){cout<<1<<endl;continue;} if(len == 1){cout<<-1<<endl;continue;} if(len > 2){cout<<2<<endl;continue;} if(a[1]*(y-b[0])==b[1]*(x-a[0])||b[0]*(x-a[1])==a[0]*(y-b[1])) {cout<<3<<endl;continue;} cout<<2<<endl; } return 0; }