首页 新闻 会员 周边 捐助

请各位大佬帮我看看这道题,谢谢!

0
悬赏园豆:200 [待解决问题]

题目描述

YJC最近在steam.上氪了不少金,但他还想氪更多。steam保证了不同的两款游戏的价格一定不同,并且游戏的价格- - 定是正整数。现在YJC已经买下了n款不同的游戏,价格分别为a1、a2、 .... an。 YJC手头还有m元,他想知道他最多还能入手多少款他没有的游戏?

输入

第一行包含两个整数n和m,表示YJC已经买下的游戏数和YJC的钱数。
第二行包含n个整数a,表示YJC已经入手的每一款游戏。

输出

第一行包含-一个整数k,表示YJC最多还能买下多少款游戏。
第二行包含k个整数b,表示YJC接下来要买下的每一款游戏。 如果有多组解,输出
字典序最小的。

样例输入
4 14
4 6 8 12
样例输出
4
1 2 3 5

提示

对于100%的数据,满足1<=n<=10的5次,1<=m,ai<,10的9次。

北城柳絮飘的主页 北城柳絮飘 | 初学一级 | 园豆:4
提问于:2020-08-20 08:37
< >
分享
所有回答(5)
0

题目的出处是啥?

Conan-jine | 园豆:1272 (小虾三级) | 2020-08-20 12:31

正睿oi

支持(0) 反对(0) 北城柳絮飘 | 园豆:4 (初学一级) | 2020-08-20 12:32
0

类似这样?
private static void gameCnt(int n, int m, Integer[] mArr) {
System.out.println("n:" + n + ", m:" + m + "mArr:" + Arrays.toString(mArr));
if(null == mArr || n < 0 || n != mArr.length){
System.out.println("fail");
return;
}
List<Integer> ml = Arrays.asList(mArr);
int i = 1;
List<Integer> wm = new ArrayList<>();
while(m > 0 && m >= i){
if(!ml.contains(i)){
wm.add(i);
m = m - i;
}
i++;
}
System.out.println(wm);
}

WMG-Eight | 园豆:973 (小虾三级) | 2020-08-20 12:31

谢谢

支持(0) 反对(0) 北城柳絮飘 | 园豆:4 (初学一级) | 2020-08-20 12:32
0

文字很长,核心重点:两款游戏的价格一定不同且价格一定是正整数。
所以整个题目可以简单化为:YJC 有一个整数列表x和一个整数m。从正整数a=1开始逐渐+1遍历,如果不在列表x中,则加入返回列表y中,且m-a。
实现如下:

        [Theory]
        [InlineData(new int[] { 4, 6, 8, 12 }, 14, 4)]
        public void SampleTest(int[] owned, int money, int expectBuyCount)
        {
            int price = 1;  //游戏价格
            int count = 0;  //可买数量
            List<int> buy = new List<int>();    //可买游戏价格表
            while (money > 0)
            {
                //钱不够了
                if (money < price)
                {
                    break;
                }
                //已经买过了
                if (owned.Contains(price))
                {
                    price++;
                    continue;
                }
                //买下游戏
                money = money - price;
                buy.Add(price);
                price++;
                count++;
            }

            Assert.True(expectBuyCount == count);
        }

优化点:
每次都要去owned列表中去判断存不存在,考虑优化
1.把owned列表转为hash表,这样每次判断o(1)的时间复杂度
2.如果owned列表是有序的,可以遍历owned列表,然后每次遍历owned列表i和i+1之间的整数,即为可买的数

gt1987 | 园豆:1150 (小虾三级) | 2020-08-20 16:25
0

全部遍历是可以,但是肯定有更好的办法,这个程序,我觉写的好的话没半天功夫搞不定,搞不好需要1天甚至更多。

首先给定了钱数,可以先算最多可以分多少组,这样就会省下很多遍循环,可以通过计算从1加到n的和是小于m的最大值时的n作为最多可以分的组数

然后在分的时候还可以加一些判断减少循环,比如,如果要买3个游戏,总钱数是m,当这3个游戏里最低的价格高于m的1/3时就不用看后面的了

会长 | 园豆:12463 (专家六级) | 2020-08-20 17:41
0

简单写了一下,能得到题主解。只是要多组解的话估计用上hashmap就行
代码如下:

public class Test09 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();

    ArrayList<Integer> al = new ArrayList();  //用一个数组来装已买的各种游戏的价钱
    for (int i = 0; i < n; i++) {
        al.add(sc.nextInt());
    }

    ArrayList<String> bl = new ArrayList();  //用另一个数组来装还能买的游戏价钱
    int sum = 0;
    int count = 0;
    loop: for (int i = 1; ; i++) {
        if (al.contains(i)) {  //如果该价钱已经买了则直接跳过,继续循环
            continue;
        } else {
            sum += i;
            count ++;
            bl.add(i+"");  //将价钱添加到数组前先转换为字符串,方便打印,避免打印时与索引冲突
            if (sum > m) {  //如果总价钱超了,把最后一个游戏退回去,然后跳出整个循环
                sum -= i;
                count --;
                bl.remove(i+"");
                break loop;  
            }
        }
    }
    System.out.println(bl.size());
    for (int i = 0; i < bl.size(); i++) {
        System.out.print(bl.get(i) + " ");
    }
}

}

JustCrazy | 园豆:68 (初学一级) | 2020-08-25 19:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册