1.题目链接。题目大意:给定两个数组,a,b.用a,b构造c。其中c[i]=a[i]*d+b[i],d是任意的。现在让你来选择合适的d,然后使得c中0尽可能的多。求出这个最多的0.
2.这个最开始的想法就是对(-b/a)计数,然后发现精度不够。那么就对这个点计数好了,求一下gcd,然后对最简的点计数,注意0的情况特判掉。当然,这不是一个很好的写法,这个题显然是可以把这两个数求完gcd之后哈希掉的,比如哈希成一个ll(具体的哈希方法可以是,把a[i]作为ll的高32位,b[i]作为ll的低32位)。然后对这个ll计数,这样就不再特判0。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
#define ll long long
ll gcd(ll a, ll b)
{
return b == 0 ? a : gcd(b, a%b);
}
ll a[N];
ll b[N];
#pragma warning(disable:4996)
typedef pair<ll, ll>pll;
map<pll, int>mp;
int main()
{
int n;
while (cin >> n)
{
mp.clear();
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n; i++)
{
cin >> b[i];
//scanf("%lld", &b[i]);
}
int ans = 0;
int zero = 0;
for (int i = 0; i < n; i++)
{
if (a[i] != 0)
{
//cout << (-b[i]/a[i]) << " " << endl;
int tem = gcd(a[i], b[i]);
pll a1 = make_pair(-1 * b[i]/tem, a[i]/tem);
mp[a1]++;
}
else
if (b[i] == 0)
{
zero++;
}
else
{
continue;
}
}
auto iter = mp.begin();
for (iter = mp.begin(); iter != mp.end(); iter++)
{
ans = max(ans, iter->second);
}
if (zero)ans += zero;
cout << ans << endl;
}
}
/*
2
999999999 1000000000
999999998 999999999
*/