zoukankan      html  css  js  c++  java
  • Light OJ 1341 Aladdin and the Flying Carpet

    题意:求大于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偏小才这么做的,两种方法个人感觉差点儿相同,希望各位大牛指正。

  • 相关阅读:
    新工作 Day24 周六
    新工作 Day23 周五
    新工作 Day22 周四
    新工作 Day21 周三
    新工作 Day20 周二
    新工作 Day19 周一
    新工作 Day18 周日
    新工作 Day17 周六
    java线程池 多线程搜索文件包含关键字所在的文件路径
    java实现搜索文件夹中所有文件包含的关键字的文件路径(递归搜索)
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6943374.html
Copyright © 2011-2022 走看看