题意:求大于b的a的因数对有几组。例10 2结果为{2,5},12 2结果为{2,6}{3,4}-----不反复
解一:分解质因数+DFS
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
typedef long long ll;
const int maxn=1000005;
int prime[maxn];
int num[maxn];
int dig[200];
int dignum[200];
int p;
void inti() //筛选素数
{
p=0;
memset(prime,0,sizeof(prime));
memset(num,0,sizeof(num));
for(int i=2;i<maxn;i++)
{
if(!prime[i])
{
num[p++]=i;
for(int j=2;j*i<maxn;j++)
prime[i*j]=1;
}
}
return ;
}
ll pp;
void dfs(ll tot,int t,int l,ll a,ll b) //dfs找到全部符合的因数
{
if(((double)tot*tot)>=a)
return ;
if(tot>=b)
pp++;
for(int i=t;i<l;i++)
{
if(dig[i])
{
ll temp=tot*dignum[i];
if(((double)temp*temp)>=a)
return ;
dig[i]--;
dfs(temp,i,l,a,b);
dig[i]++;
}
}
return ;
}
int main()
{
ll a,b;
int t;
inti();
while(cin>>t)
{
for(int i=1;i<=t;i++)
{
pp=0;
cin>>a>>b;
double limit=sqrt(a*1.0);
if(b>=limit)
{
cout<<"Case "<<i<<": 0"<<endl;
continue;
}
ll temp=a;
int j=0;
int time=0;
while(j<=p) //全部的质因数
{
if((ll)num[j]*num[j]>temp) //小小的剪枝
break;
int flag=0;
while(!(temp%num[j]))
{
temp/=num[j];
flag++;
}
if(flag)
{
dignum[time]=num[j];
dig[time++]=flag;
}
j++;
}
if(temp!=1)
{
dignum[time]=temp;
dig[time++]=1;
}
/*for(j=0;j<time;j++)
cout<<dignum[j]<<" "<<dig[j]<<endl;*/
dfs(1,0,time,a,b);
cout<<"Case "<<i<<": "<<pp<<endl;
}
}
return 0;
}
解二:直接计算
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
typedef long long ll;
const int maxn=1000005;
int prime[maxn];
int num[maxn];
int dig[200];
int dignum[200];
int p;
void inti() //找素数
{
p=0;
memset(prime,0,sizeof(prime));
memset(num,0,sizeof(num));
for(int i=2;i<maxn;i++)
{
if(!prime[i])
{
num[p++]=i;
for(int j=2;j*i<maxn;j++)
prime[i*j]=1;
}
}
return ;
}
/*ll pp;
void dfs(ll tot,int t,int l,ll a,ll b)
{
if(((double)tot*tot)>=a)
return ;
if(tot>=b)
pp++;
for(int i=t;i<l;i++)
{
if(dig[i])
{
ll temp=tot*dignum[i];
if(((double)temp*temp)>=a)
return ;
dig[i]--;
dfs(temp,i,l,a,b);
dig[i]++;
}
}
return ;
}*/
int main()
{
ll a,b;
int t;
inti();
ll sum;
while(cin>>t)
{
for(int i=1;i<=t;i++)
{
sum=1;
cin>>a>>b;
if(((double)b*b)>=a)
{
cout<<"Case "<<i<<": 0"<<endl;
continue;
}
ll temp=a;
int j=0;
int time=0;
while(j<=p)
{
if((double)num[j]*num[j]>temp)
break;
int flag=0;
while(!(temp%num[j]))
{
temp/=num[j];
flag++;
}
sum*=(flag+1); //排列组合。把全部的情况拿出来
j++;
}
if(temp!=1)
{
sum*=2; //还有没除尽的要给全部可能性乘2
}
sum/=2; //直接除2,把反复的部分和正方形除去了
ll limit=sqrt(a*1.0);
for(j=1;j<b;j++) //去掉不符合要求的矩形
if(!(a%j))
sum--;
/*for(j=0;j<time;j++)
cout<<dignum[j]<<" "<<dig[j]<<endl;*/
//dfs(1,0,time,a,b);
cout<<"Case "<<i<<": "<<sum<<endl;
}
}
return 0;
}
第一种方法easy爆站。另外一种方法算是凑着它数据的b偏小才这么做的,两种方法个人感觉差点儿相同,希望各位大牛指正。