赞
踩
总结一下做题的过程:
刚开始以为第一题很简单,因为忽略了一个很重要的条件,再去读题发现没注意到那个要点,然后开始重来,发现下不了笔,整个人都傻了。整个一大惨败,前一个小时根本没思路,一个小时后发现可以分情况考虑,但是当时又遇到了一个问题,就是不知道怎么去分是否要退出的情况。做完第一题剩下10几分钟,直接交卷了,麻了……
第二题没怎么看,感觉是这三题里面最难的。
最后一道题感觉用回溯可以做,但是我由于时间剩得不多了,当时比较慌,找不到递归出口的条件,下来跟他们讨论了一下这个题,说是要么需要遍历一遍,要么就是建树,但是我觉得这题可以直接看作是没有回路的图。但是呢,想到他们说2022.4.13那次的最后一题用回溯做完过了5%,原因是超时,就心态崩了,还是果断放弃,直接System.out.println(-1);过了10%,溜了溜了……
题目描述:小聪入职新公司,参加线上的新员工必备考试,考试共25题,依次是10个判断题(每题2分)、10个单选题(每题4分)和5个多选题(每题8分),总分100分。
考题只能顺序作答,答对题目获得相应的分数,答错题目获得0分,考试系统不提示作答是否正确,答题过程中如果累积有3道题答错,直接中止考试并计算考试分数。
小聪考试结果是N分(0<=N<=100),请根据小聪的分数,算出所有可能的答题情况的个数。
输入:
整数,表示小聪的考试得分N,N为偶数,0<=N<=100(N不会是不可能考出来的分数)。
输出:
整数,表示所有可能的答题情况的个数
样例1:
输入:94
输出:100
解释:有1道判断题和1道单选题答错,其余的题都答对
样例2:
输入:100
输出:1
解释:所有的都答对
思路:
三种情况:
比如:
设判断题个数为x,单选个数为y,多选个数为z
x可以是8,9,10
当x = 8时,y只能是10
当x = 9时,y可以是9,10
当x = 10时,y可以是8,9,10
z = (N - 2x - 4y) / 8
比如:情况3 且x = 9时,判断错了一道,单选只能错1道或者0道,如果单选错了2道的话,就直接结束了,就没有答对的多选题了。这种是属于第2种情况,判断题对9道,单选对8道,总分是9 * 2 + 8 * 4 = 50
综上可以根据N计算出x,y,z。
然后根据x,y,z计算可能的答题组合。
第一种情况:2x = N
当x 为8,9,10的时候,即最多错2道,就是10道题中选择x道题,结果就是组合数C(10, x)
如果x < 8,这种情况要注意,不能是C(10, x),比如x=2时,最多只能做到第4题,第五题肯定是错的,如果第五题是对的,那至少也对了3道题。所以结果应该是C(x + 2, x)。此注意的点对下面的两种情况都满足。
第二种情况:2x + 4y = N
当x为8时,计算出y,如果y不是整数,那这个组合无效。如果y为整数,就符合条件,比如56分时x = 8,y = 10
那结果就是C(10, x) * C(10, y),这里计算C时跟上一步说的一样,要考虑中途结束答题的情况。
此时又有个注意的点,比如当x = 8时,y = 5时,y只能是单选题的前5个,因为判断题已经错了两个了,如果单选题前5个中间再错一个就结束答题了,所以就算y的组合数的时候,应该是C(y, y) = 1,而不是C(y + 2, y)。结果是C(10, x) * C(y, y)。
再比如当x = 9时,y = 5的话,单选题的前5个里只能错1个,组合数就是C(y + 1, y),结果是C(10, x) * C(y + 1, y)
然后把x的三种情况的结果相加就是最后的结果。
第三种情况和第二种类似,只是计算z的时候要先根据x把y的范围找出来,再把y的可能列出来,再去计算z。
下面截图框出来的部分就是处理上面说的注意的点。
代码:
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); int count = 0; if(N <= 18){ int x = N / 2; int y = 0; int z = 0; count = count(x, y, z); }else if(20 <= N && N <= 58){ int[] xArr = {8, 9, 10}; for(int x: xArr){ int r = (N - 2 * x) % 4; if(r != 0){ continue; } int y = (N - 2 * x) / 4; count += count(x, y, 0); } }else if(60 <= N){ int[] xArr = {8, 9, 10}; for(int x: xArr){ int[] yArr = {10}; if(x == 9){ yArr = new int[]{9, 10}; } if(x == 10){ yArr = new int[]{8, 9, 10}; } for(int y: yArr){ int r = (N - 2 * x - 4 * y) % 8; if(r != 0){ continue; } int z = (N - 2 * x - 4 * y) / 8; count += count(x, y, z); } } } System.out.println(count); } public static int count(int x, int y, int z){ int m1 = x + 2; if(m1 > 10){ m1 = 10; } int m2 = y + (2 - (10 - x)); if(m2 > 10){ m2 = 10; } int m3 = z + (2 - (10 - x) - (10 - y)); if(m3 > 5){ m3 = 5; } int c1 = c(m1, x); int c2 = c(m2, y); int c3 = c(m3, z); return c1 * c2 * c3; } public static int c(int m, int n){ int sum1 = 1; for(int i = 1;i <= n;i++){ sum1 = sum1 * i; } int sum2 = 1; for(int j = m;j >= m - n + 1;j--){ sum2 = sum2 * j; } return sum2 / sum1; } }
期待有更好思路的你们提供更优的方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。