给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2},{N,1}.求出有多少个集合满足:第一个元素是A的倍数且第二个元素是B的倍数。
提示:
对于第二组测试数据,集合分别是:{1,10},{2,9},{3,8},{4,7},{5,6},{6,5},{7,4},{8,3},{9,2},{10,1}.满足条件的是第2个和第8个。
Input
第1行:1个整数T(1<=T<=50000),表示有多少组测试数据。 第2 - T+1行:每行三个整数N,A,B(1<=N,A,B<=2147483647)
Output
对于每组测试数据输出一个数表示满足条件的集合的数量,占一行。
Input示例
2 5 2 4 10 2 3
Output示例
1 2
这题wa了N+1发
从大神学习:http://blog.csdn.net/u010885899/article/details/46761757
#include <iostream>
#include <vector>
#include <algorithm>
#include<stdio.h>
using namespace std;
//扩展欧几里德
//求解方程ax+by=gcd(a,b) d=gcd(a,b)
void ex_gcd(long long a,long long b,long long &d,long long &x,long long &y)
{//gcd(a,0)=1*a+0*0 递归出口
if(b==0)
{
d=a;
x=1;
y=0;
}
else
{
ex_gcd(b,a%b,d,y,x);
y=y-x*(a/b);//先记住
}
}
long long slove()
{
//求ax+by=n+1有多少组整数解
long long x,y,a,b,n,d;
cin>>n>>a>>b;
//求解方程ax+by=gcd(a,b) d=gcd(a,b)
ex_gcd(a,b,d,x,y);
long long z=a*b/d; //最小公倍数
//n+1必须是gcd(a,b)的倍数
if((n+1)%d)
return 0;
x=x*((n+1)/d); //求解 ax+by=n+1 x
long long r=b/d;
x=(x%r+r)%r;//求解最小的x
if(x==0) x=r;
long long remain=n-x*a;
long long ans=0;
if(remain<0)
return 0;
else
{
ans=1; //最小x解
//remain/Lcm(a,b)就是看看有多少个 ab倍数
ans=ans+remain/z;
}
return ans;
}
int main()
{
int t;
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
long long ans=slove();
cout<<ans<<endl;
}
return 0;
}