Problem Description
有一个方程 ax+by=n,题目给你一个n,问你有多少对(a,b)其中 a小于b 满足方程,x, y只能是正整数。
例:
4
有两对分别是(1,2), (1, 3)。
思路:
比赛中,大体思路是想对了,一些细节没处理好。
因为题目允许的时间复杂度很大,所以可以O(n^2)的复杂度过题,虽然n = 3e5。
by = n - ax,我们可以枚举a和x 求出by。我们需要提取出b,就是需要知道by的所有因数。还需要注意的一个细节,对于同一个a,b不能重复。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 3e5+100;
vector<int> vec[N];
int vis[N];
int main()
{
int n;
while(~scanf("%d", &n))
{
int num = 0;
for(int i = 1; i < n; i++)//枚举出所有数的因数,为了一会儿用
{
vec[i].clear();
for(int j = 1; j*j <= i; j++)
{
if(i % j == 0)
{
vec[i].push_back(j);
if(j*j != i) vec[i].push_back(i/j);
}
}
sort(vec[i].begin(), vec[i].end(), greater<int>());
}
memset(vis, 0, sizeof(vis));
for(int a = 1; a < n; a++)
{
for(int x = 1; x < n; x++)
{
if(a*x >= n) break;
int t = n - a*x;//t就是b*y
for(int i = 0; i < vec[t].size(); i++)
{
if(vec[t][i] > a)//得满足b > a
{
if(vis[vec[t][i]] != a)//同一个a的b不能重复
{
num++;
vis[vec[t][i]] = a;
}
}
else break;
}
}
}
printf("%d\n", num);
}
return 0;
}