題意:求大於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;
}
第一種方法容易爆站,第二種方法算是湊着它數據的b偏小才這麼做的,兩種方法個人感覺差不多,希望各位大牛指正。