• 【bzoj2257】[Jsoi2009]瓶子和燃料 扩展裴蜀定理+STL-map


    题目描述

    给出 $n$ 个瓶子和无限的水,每个瓶子有一定的容量。每次你可以将一个瓶子装满水,或将A瓶子内的水倒入B瓶子中直到A倒空或B倒满。从中选出 $k$ 个瓶子,使得能够通过这 $k$ 个瓶子凑出的最小体积最大。求这个体积。

    输入

    第1行:2个整数N,K,  
    第2..N 行:每行1个整数,第i+1 行的整数为Vi  

    输出

    仅1行,一个整数,表示火星人给出燃料的最大值。

    样例输入

    3 2 


    4

    样例输出

    4


    题解

    扩展裴蜀定理+STL-map

    显然通过容量为 $v_1,v_2,...,v_k$ 的瓶子能够凑出的容量 $c$ 满足:$v_1x_1+v_2x_2+...+v_kx_k=c$ 存在整数解。

    根据裴蜀定理有 $gcd(v_1,v_2,...,v_k)|c$ 。因此最小正整数就是它们的 $gcd$ 。

    原问题转化为:从 $n$ 个数中选出 $k$ 个,使得它们的 $gcd$ 最大。

    枚举所有数的所有约数,判断其是否是至少 $k$ 个数的约数,并更新答案即可。这个过程可以使用STL-map维护。

    时间复杂度 $O(nsqrt v+nlog n·约数个数)$ ,由于约数个数极少,远达不到 $sqrt v$ ,因此可以通过。

    #include <map>
    #include <cstdio>
    using namespace std;
    map<int , int> mp;
    map<int , int>::iterator it;
    int main()
    {
    	int n , k , i , j , x , ans = 0;
    	scanf("%d%d" , &n , &k);
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		scanf("%d" , &x);
    		for(j = 1 ; j * j <= x ; j ++ )
    		{
    			if(x % j == 0)
    			{
    				mp[j] ++ ;
    				if(j * j != x) mp[x / j] ++ ;
    			}
    		}
    	}
    	for(it = mp.begin() ; it != mp.end() ; it ++ )
    		if(it->second >= k)
    			ans = max(ans , it->first);
    	printf("%d
    " , ans);
    	return 0;
    }
    
  • 相关阅读:
    IfcLightSourceSpot
    IfcLightSourcePositional
    IfcLightSourceGoniometric
    IfcLightSourceDirectional
    IfcLightSourceAmbient
    IfcLightSource
    从一系列的图片文件夹中随机抽取图片
    IfcPolygonalBoundedHalfSpace
    IfcBoxedHalfSpace
    IfcHalfSpaceSolid
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8610437.html
Copyright © 2020-2023  润新知