zoukankan      html  css  js  c++  java
  • LightOJ 1341

    Sample Input
    2
    10 2
    12 2

    Sample Output
    Case 1: 1
    Case 2: 2

    题目大意:给你两个数a和b,a是长方形的面积(这个长方形是非常单纯的长方形,他没有两条相等的边),长方形的宽大于等于b(,不管宽怎么膨胀,宽是永远小于长滴)。而我们就是要求出满足条件的长宽的对数。

    解题思路:因为今天刚学的唯一分解定理,知道要用,但不知道如何用,所以就看了看dalao的题解,恍然大悟~~,唯一分解定理有以下几条应用:
    在这里插入图片描述
    目前我也只懂前两条,太菜了,显然,这题需要用到定理的第一条,那应该怎么用呢,首先我们可以利用第一条求出a的正因子个数除以2就是长宽的对数,然后求出[1,b)内a的正因子个数,两者一减,就是所求的结果了。

    Code:

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<map>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6+10;
    bool p[maxn];
    ll prime[maxn],cnt;
    
    void get_prime(){//素数打表 
    	cnt=0;
    	memset(prime,0,sizeof(prime));
    	memset(p,0,sizeof(p));
    	for(ll i=2;i<maxn;i++){
    		if(!p[i]){
    			prime[cnt++]=i;
    			for(ll j=i+i;j<maxn;j+=i){
    				p[j]=1;
    			}
    		}
    	}
    }
    
    ll cont(ll a){//求a的正因子个数 
    	ll ans=1;
    	ll i=0,num=0;
    	while(prime[i]<a&&i<cnt){
    		while(a%prime[i]==0){
    			a/=prime[i];
    			num++;
    		}
    		ans*=(num+1);
    		num=0;
    		i++;
    	}
    	if(a>1) ans*=1+1;
    	return ans;
    }
    
    int main(){
    	int t,k=1;
    	get_prime();
    	scanf("%d",&t); 
    	while(t--){
    		ll a,b;
    		ll cnt=0;
    		scanf("%lld %lld",&a,&b);
    		if(b>=sqrt(a)){//如果b大于等于a的平方根,那么长宽的乘积就会大于等于a,而长宽不能相等。 
    			printf("Case %d: %lld
    ",k++,0);
    			continue;
    		}
    		for(ll i=1;i<b;i++){
    			if(a%i==0) cnt++;
    		}
    		ll temp=cont(a)/2;
    //		cout<<temp<<" "<<cnt<<endl;
    		printf("Case %d: %lld
    ",k++,temp-cnt);
    	}
    	
    	return 0;
    }
    
    七月在野,八月在宇,九月在户,十月蟋蟀入我床下
  • 相关阅读:
    [算法初步]希尔排序
    逆波兰表达式1(简介)
    [数据结构]之链表
    [数据结构]之栈
    [算法初步]之归并排序
    [算法初步]之快速排序
    [算法初步]之冒泡排序
    逆波兰表达式2中缀转后缀表达式)
    [算法初步]之简单选择排序
    [数据结构]之顺序表
  • 原文地址:https://www.cnblogs.com/voids5/p/12695024.html
Copyright © 2011-2022 走看看