sgu 491 Game for Little Johnny
http://acm.sgu.ru/problem.php?contest=0&problem=491
给一个N,求有多少对A和B(1 ≤ A < B ≤ N),让方程Ax+By=N有自然数解。
3091MS:
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
#define MAXN 100001
vector<int> fac[MAXN];
int tmp[MAXN*100];
void get_fac(int n)
{
if(fac[n].size()>0) return;
int i,num=0;
for(i=1; i*i<=n; i++)
{
if(n%i==0)
{
tmp[num++] = i;
tmp[num++] = n/i;
// printf("n=%d i=%d\n",n,i);
}
}
sort(tmp,tmp+num);
fac[n].push_back(tmp[0]);
for(i=1; i<num; i++)
{
if(tmp[i]!=tmp[i-1]) fac[n].push_back(tmp[i]);
}
}
void solve(const int n)
{
int i,a,ax,b,by,num,ans=0;
for(i=1; i<=n; i++) get_fac(i);
for(a=1; a<n; a++)
{
num = 0;
for(ax=a; ax<n; ax+=a)
{
by = n - ax;
for(vector<int>::reverse_iterator rit = fac[by].rbegin(); rit != fac[by].rend(); rit++)
{
b = *rit;
if(b > a) tmp[num++] = b;
else break;
}
}
if(!num) continue;
sort(tmp,tmp+num);
ans++;
for(int t=1; t<num; t++)
if(tmp[t]!=tmp[t-1]) ans++;
}
printf("%d\n",ans);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("tdata.txt","r",stdin);
#endif
int n;
while(scanf("%d",&n)!=EOF)
{
solve(n);
}
return 0;
}
浙公网安备 33010602011771号