还是没有想到简单的方法,具体咋样自己百度吧。。。。方法搞得麻烦,快把自己整吐了,好在最后AC了。。。。。。T__T
首先是特殊情况,分别是a=0或b=0时,这个省略了
接下来:根据题意,(A0x +B0y) % n =0 转换为 A0x+ B0y = nk,首先判断 n 是否整除g=gcd(a0,b0),如果不整除,则该方程无解,令n1 = n*g/gcd(n,g)。如果n整除g,则n1 =g
然后得:x = (n1*k -b0*y)/a0,并求出方程的一个特解y0,则y =k( y0 + m*d) , d =a0/g,m为任意数
把x,y带入Ax + By = (1/a0)*[(a*n1+(a0*b-a*b0)*y0) k + (a0*b-a*b0)*a0/g],并令t = a0*b-b0*a;
接下来,枚举T,再枚举A和B。。。。。。附代码:
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#define ll __int64
#define N 10003
#define pb push_back
using namespace std;
vector<ll>res[N];
ll a0,b0,n,g,sum;
void extend(ll a,ll b,ll &x,ll &y)
{
if (!b)
{
x=1;y=0;
}
else
{
extend(b,a%b,x,y);
ll temp=x;x=y;
y=temp-a/b*y;
}
}
void deal(ll y0,ll t,ll n1)
{
ll x1,y1,d,a,b;
extend(b0,a0,x1,y1);
y1=y1*t/g;
d=b0/g;
y1=(y1%d+d)%d;
for (b=y1;b<n;b+=d)
{
a=(a0*b-t)/b0;
ll f = a*n1+t*y0;
if (f%(n*a0)!=0) continue;
if (a>=0&&a<n)
{
sum++;
res[a].pb(b);
}
}
}
ll gcd(ll a,ll b)
{
if (a<b) return gcd(b,a);
if (!b) return a;
else return gcd(b,a%b);
}
void special()
{
int i;
if (!a0&&!b0)
{
cout<<1<<endl;
cout<<0<<" "<<0<<endl;
}
else if (a0)
{
cout<<(n-1)/a0+1<<endl;
for (i=0;i<n;i+=a0) cout<<i<<" "<<0<<endl;
}
else
{
cout<<(n-1)/b0+1<<endl;
for (i=0;i<n;i+=b0) cout<<0<<" "<<i<<endl;
}
}
int main()
{
ll x1,y1,i,d,t,n1;
cin>>n;
cin>>a0>>b0;
if (!a0||!b0)
{
special();
//system("pause");
return 0;
}
g=gcd(a0,b0);
ll y0,p,q;
if (n%g!=0) n1=n*g/gcd(n,g);
else n1=n;
extend(a0,b0,x1,y1);
y0=y1*n1/g;
p=-b0/g;
q=a0/g;
for (i=p;i<=q;i++)
{
t=i*n*g;
deal(y0,t,n1);
}
cout<<sum<<endl;
for (i=0;i<n;i++)
if (res[i].size())
{
sort(res[i].begin(),res[i].end());
for (int j=0;j<res[i].size();j++) cout<<i<<" "<<res[i][j]<<endl;
}
// system("pause");
return 0;
}