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

  • 相关阅读:
    JAVA基础——编程练习(二)
    JAVA基础——面向对象三大特性:封装、继承、多态
    JVM内存
    50. Pow(x, n) (JAVA)
    47. Permutations II (JAVA)
    46. Permutations (JAVA)
    45. Jump Game II (JAVA)
    43. Multiply Strings (JAVA)
    42. Trapping Rain Water (JAVA)
    41. First Missing Positive (JAVA)
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6943374.html
Copyright © 2011-2022 走看看