[BZOJ 2257][JSOI2009] Bottle and Fuel Problem Solution (GCD)

[BZOJ 2257][JSOI2009] Bottles and Fuel

Description

Jyy always wanted to return to Earth as soon as possible, but unfortunately his spaceship ran out of fuel.
One day he went to the Martian again to ask for fuel, this time the Martian agreed and asked Jyy to exchange it with the bottle on the spaceship. There are a total of N bottles (1<=N<=1000) on jyy
's spacecraft. After negotiation, the Martians only need K of them. After jyy
gave the K bottles to the Martian, the Martian used them to fill jyy with some fuel. All the bottles have no scale, only
the capacity is marked on the bottle mouth, the capacity of the ith bottle is Vi (Vi is an integer, and 1<=Vi<=1000000000).
Martians are stingy, and they don't fill all their bottles with fuel. After they got the bottle, they would go to the fuel
depot and fiddle around with it and get a little bit of fuel to cross. Of course jyy knew that they would do this, so he knew in advance what the
Martians were tinkering with. Martians can only do the following three operations in the fuel depot: 1. Fill a certain bottle with fuel;
2. Pour all the fuel in a certain bottle back into the fuel depot; 3. Pour the fuel from bottle a to the bottle b, until bottle b is full
or bottle a is empty. Losses during fuel dumping are negligible. The fuel that the Martian took out was, of course,
the smallest positive volume that could be obtained from these operations.
jyy knew that Martians might be forced to give different volumes of fuel for different bottle combinations. jyy wants to find
the optimal combination of bottles so that Martians give as much fuel as possible.

Input

Line 1: 2 integers N,K,
lines 2..N: 1 integer per line, the integer in line i+1 is Vi

Output

Only 1 line, an integer, representing the maximum fuel value given by Martians.

Solution

1. Considering that Martians will only pour between bottles, not half or other magical means, so the fuel volume they can make should be a linear combination of all bottle volumes;

2. Through Pei Shu's theorem, we can easily prove that for any number of integers, the smallest positive integer they can combine is their GCD, so the answer is to find the maximum value of more than k among the divisors of all numbers;

3. Considering that the counter array cannot be opened, use the array to store all the divisors, and finally sort it again, O(n) to find the optimal solution.

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;

int n,m,divs[10000001],tot,cnt=1;

inline int rd(){
    int x=0;
    char c=getchar();
    while(!isdigit(c))c=getchar();
    while(isdigit(c)){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return x;
}

inline int mx(int x,int y){return x>y?x:y;}

inline bool cmp(int x,int y){return x>y;}

void calc(int v){
    int temp=sqrt(v);
    for(int i=1;i<temp;++i)
        if(!(v%i)){
            divs[++tot]=i;
            divs[++tot]=v/i;
        }
    if(!(v%temp)){
        divs[++tot]=temp;
        if(v/temp!=temp) divs[++tot]=v/temp;
    }
}

int main(){
    n=rd();m=rd();
    for(int i=1;i<=n;++i) calc(rd());
    sort(divs+1,divs+1+tot,cmp);
    for(int i=2;i<=tot;++i)
        if(divs[i]!=divs[i-1]){
            if(cnt>=m){printf("%d",divs[i-1]);return 0;}
            cnt=1;
        }
        else ++cnt;
    return 0;
} 

For the basic knowledge of GCD, you can refer to my essay: http://www.cnblogs.com/COLIN-LIGHTNING/p/8371664.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325380100&siteId=291194637