UVa11411 - MiniMice

Problem A : MiniMice

Time Limit : 6 seconds

Welcome to the world of mice. All mice have IDs. They are numbered orderly according to their seniority from 1. These mice live in groups. Mice of a same group have continuous ids. Mini, the mice captain (ID 0) has called mice of specific group(IDs a to b) for a session. He wanted to make a circle formation with those mice. But mice have a property : The Degree of quarrel. When 2 mice are near they quarrel to an extent that is proportional to the difference in the number of factors of their individual ids. For example when 2 mice of ids 4 and 24 are near they quarrel 5 units(say). Number of factors of 4 � 3(1,2,4). 24 � 8 (1,2,3,4,6,8,12,24). Also the strength of quarrel affects the neighbourhood. So, Mini, the mice captain wants to minimize the strength of the maximum quarrel in that circle by arranging the mice appropriately. Note that the circle formation is mandatory. Help Mini , the mice caption to MiniMice the quarrel.

Input:


First line contains number of test cases.
Each test case is represented by a space separated list of 2 ids representing the group of mice "ab" . All mice with ids a<=id<=b are present in the session. 1 <= a <= 4999999 ; a < b <= 5000000. 

Output:



Output one line for each test case , the minimized maximum quarrel value. Quarrel value between 2 mice = Absolute Difference in Number of factors of their IDs. 

Sample Input :


2
5 8
21 24

Sample Output:


2
4

Explanation:


Case 1:
ID - No. of factors
5 - 2
6 - 4
7 - 2
8 - 4
5-6-7-8-5 is a good arrangement. 4-2 = 2.

Case 2:
ID - No. of factors
21 - 4
22 - 4
23 - 2
24 - 8
24-21-23-22-24 is a good arrangement. 8-4 = 4.

Problem Setter : Ramgopal K 
Written for CarteBlanche '08


题目大意是 将a到b这b-a+1个数,排成一个圆,使排列中的最大的相邻两个数的因式个数之差最小!

因式个数可以根据质因数分解以后乘法原理求得
这题因为数比较大  因此排序需要O(n)的效率
贪心方法为:将数从两个端点开始往中间放!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 5000001;
int a,b,ans,n;
int num[maxn];
bool vis[maxn];
int cnt[maxn],tmp[maxn];
vector<int> prime;
bool isprime[maxn];
void getprime(){
    memset(isprime,0,sizeof isprime);
    for(long long i = 2; i < maxn; i++){
        if(!isprime[i]){
            prime.push_back(i);
            for(long long j = i*i ; j < maxn;  j+= i )
                isprime[j] = 1;
        }
    }
}
int getc(int x){
    int ans = 1,a= 0;
    while(prime[a]*prime[a] <= x){
        int cnt = 1;
        while(x%prime[a]==0){
            x /= prime[a];
            cnt++;
        }
        a++;
        ans *= cnt;
    }
    if(x>1) ans *= 2;
    return ans;
}
void count_sort(int *a,int *b ,int k){
    int c[411];
    memset(c,0,sizeof c);
    for(int i  = 1; i <= n; i++){
        c[a[i]]++;
    }
    for(int i = 1; i <= k; i++){
        c[i] += c[i-1];
    }
    for(int i = n; i >= 1; i--){
        b[c[a[i]]]  = a[i];
        c[a[i]]--;
    }
}
int main(){

    int ncase;
    memset(vis,0,sizeof vis);
    getprime();
    cin >> ncase;
    while(ncase--){
        cin >> a >> b;
        for(int i = a; i <= b; i++){
            if(!vis[i]){
                vis[i] = 1;
                num[i] = getc(i);
            }
        }
        n = b-a+1;
        for(int i = 1; i <= n; i++)    tmp[i] = num[i+a-1];
        count_sort(tmp,cnt,410);
        int head=cnt[1],last = cnt[1];
        int i = 2;
        ans = 0;
        while(i<n){
            ans = max(ans,cnt[i]-head);
            ans = max(ans,cnt[i+1]-last);
            head = cnt[i];
            last = cnt[i+1];
            i += 2;
        }
        if(i==n){
            ans = max(ans,cnt[n]-head);
            ans = max(ans,cnt[n]-last);
        }
        cout<<ans<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值