【算法题】包子凑数-JAVA解

问题描述:

小明几乎每天早晨都会在一家包子铺吃早餐,他发现这家包子铺有N种蒸笼,其中第i种蒸笼都有非常多种,可以认为是无限种。

每当有顾客想买x种包子,卖包子的大叔都会迅速选出若干笼包子来,使得这若干笼包子中恰好有X个包子。比如一共有3种蒸笼,分别能放3、4、5个包子。当顾客想买11个时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的)。

当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有3种蒸笼,分别能放4、5和6个包子。而顾客想买7个包子时,大叔就奏不出来了。
小明想知道一共有多少种数目是包子大叔凑不出来的。


输入格式:

第一行包含一个整数N。(1 <= N<= 100)
以下N行每行包含—个整数Ai。(1 <= Aic= 100)
 

输出格式:

一个整数代表答案。如果凑不出的数目有无限多个,输出INF。

代码:

import java.io.*;
import java.util.Arrays;
public class Main {
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer st=new StreamTokenizer(br);
    public static void main(String[] args) throws Exception {
        int n = nextInt();
        int[] arr = new int[101];
        Arrays.fill(arr, 999);
        int t, s = 0;
        for (int i = 0; i < n; i++) {
            t = nextInt();
            if (arr[t] == 999) {
                arr[t] = t;
                s++;
            }
        }
        Arrays.sort(arr);//排序
        if (arr[0]==1){
            System.out.println(0);
            return;
        }
        int k = 10001;
        for (int i=0;i<s-1;i++){
            for (int j=1;j<s;j++){
                if(gcd(arr[i],arr[j])==1){
                    k=Math.min(k,arr[i]*arr[j]);
                }
                if (k==arr[i]*arr[j]||arr[i]*arr[j+1]>=k)
                    break;
            }
            if (arr[i]*arr[i+1]>=k){
                break;
            }
        }
        int []sk=new int[101];
        for (int i=0;i<s;i++){
            for (int j=2;j<=arr[i];j++){
                if (arr[i]%j==0){
                    sk[j]++;
                }
            }
        }
        Arrays.sort(sk);
        if (k>10000&&sk[100]==n){
            System.out.println("INF");
            return;
        }
        int []crr=new int[k+1];
        int []drr=new int[k+1];
        int m=0,co,ss;
        for (int i=0;i<s;i++){
            co=m;
            for (int y=0;y<co;y++){
                for (int j=1;j<=(k-drr[y])/arr[i];j++){
                    ss=drr[y]+arr[i]*j;
                    if (crr[ss]==0){
                        crr[ss]=ss;
                        drr[m]=ss;
                        m++;
                    }
                }
            }
            for (int j=1;j<=k/arr[i];j++){
                if (arr[i]*j>k){
                    break;
                }
                if (crr[arr[i]*j]==0){
                    drr[m]=arr[i]*j;
                    crr[arr[i]*j]=arr[i]*j;
                    m++;
                }
            }
        }
        System.out.println(k-m);
    }
    static  int nextInt() throws Exception{
        st.nextToken();
        return (int)st.nval;
    }
    public static int gcd(int a,int b){
        return b==0?a:gcd(b,a%b);
    }
}


 

猜你喜欢

转载自blog.csdn.net/SLT1210/article/details/123671522