【cf 1133D】注意一下小的细节

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
*/

猜你喜欢

转载自blog.csdn.net/weixin_41863129/article/details/89526772