题目描述
小蓝教的编程课有 N 名学生,编号依次是 1 . . . N。第 i 号学生这学期刷题的数量是 Ai。
对于每一名学生,请你计算他至少还要再刷多少道题,才能使得全班刷题比他多的学生数不超过刷题比他少的学生数。
输入格式
第一行包含一个正整数 N。
第二行包含 N 个整数
输出格式
输出 N 个整数,依次表示第 1 . . . N 号学生分别至少还要再刷多少道题。
样例输入
5
12 10 15 20 6
样例输出
0 3 0 0 7
提示
对于 30% 的数据,1 ≤ N ≤ 1000, 0 ≤ Ai ≤ 1000.
对于 100% 的数据,1 ≤ N ≤ 100000, 0 ≤ Ai ≤ 100000.
我的代码:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
int []num=new int[N];
for(int i=0;i<N;i++) {
num[i] = sc.nextInt();
}
HashMap<Integer,Integer> map=new HashMap<>();
for(int i=0;i<N;i++){
map.put(i,num[i]);
}
List<Integer> value=new ArrayList<>();
for (int i=0;i<N;i++){
value.add(map.get(i));
}
Collections.sort(value);
int []count=new int[N];
int j=0;
for(int x:value){
count[j]=x;
j++;
}
int middle=count[N/2];
for(int i=0;i<N;i++){
if(map.get(i)<middle&&N%2!=0){
System.out.print(middle-map.get(i)+1);
System.out.print(" ");
}
else if(map.get(i)<middle&&N%2==0){
System.out.print(middle-map.get(i));
System.out.print(" ");
}
else{
System.out.print(0);
System.out.print(" ");
}
}
sc.close();
}
}
十个测试点只有三个通过,哪里出错了?
#!/sur/bin/nve python
# coding: utf-8
import time
def is_add(num):
''' 判定还需刷题量 '''
up = [i for i in stu if i > num] # 解析比当前学生多的刷题量。
up.sort() # 刷题量多的列表排升序。
low = [i for i in stu if i < num] # 解析比当前学生少的刷题量。
result = [] # 当前学生还需刷题量列表初值。
def count(num):
''' 递归计算 '''
if (len(up) - len(low)) > 0: # 比当前学生刷题量多、少人数差大于0,递归计算还需刷题量。
tem = up.pop(0) # 抽取比当前学生刷题量多且最接近的刷题量。
result2 = tem + 1 - num # 两人刷题量差值+1即是还需刷题量,就会会超过该名学生。
result.append(result2) # 将还需刷题量计入列表。
low.append(tem + result2) # 比当前学生刷题量少的人数 +1。
return count(num + result2) # 递归函数调用,继续计算。
count(num) # 调用函数计算还需刷题量。
return sum(result) if result else 0 # 如果有递归计算,则返回计算值;否则返回0。
if __name__ == '__main__':
start = time.time()
in_s = '''5
12 10 15 20 6'''
n = int(in_s.split('\n')[0])
stu = list(map(int, in_s.split('\n')[1].split()))
print(f"\n输入:\n{in_s}\n\n预期输出:0 3 0 0 7\n\n实际输出:{' '.join(map(str, [is_add(i) for i in stu]))}") # 用列表解析式解析每个学生还需刷题量,用jion()方法拼接输出。
#for i in stu:
#print(i, is_add(i)) # 循环遍历轮询写法。
print(f"程序用时:{time.time()-start} 秒")
(我仅会点python ,不懂Java语法,读不太明白Java代码。)只能用python 代码阐述“算法逻辑”。我用递归计算,初达预期,代码冗余,贴出是代码优化后的python 代码。每条语句都注释了,应该可以看出“算法逻辑”。算法不限语言,自由不分国界。
python 代码运行效果截屏图片
python 代码(优化后)
#!/sur/bin/nve python
# coding: utf-8
def is_add(num):
''' 判定还需刷题量 '''
up = [i for i in stu if i > num] # 解析比当前学生多的刷题量。
up.sort() # 刷题量多的列表排升序。
low = [i for i in stu if i < num] # 解析比当前学生少的刷题量。
result = [] # 当前学生还需刷题量列表初值。
def count(num):
''' 递归计算 '''
if (len(up) - len(low)) > 0: # 比当前学生刷题量多、少人数差大于0,递归计算还需刷题量。
tem = up.pop(0) # 抽取比当前学生刷题量多且最接近的刷题量。
result2 = tem + 1 - num # 两人刷题量差值+1即是还需刷题量,就会会超过该名学生。
result.append(result2) # 将还需刷题量计入列表。
low.append(tem + result2) # 比当前学生刷题量少的人数 +1。
return count(num + result2) # 递归函数调用,继续计算。
count(num) # 调用函数计算还需刷题量。
return sum(result) if result else 0 # 如果有递归计算,则返回计算值;否则返回0。
if __name__ == '__main__':
in_s = '''5
12 10 15 20 6'''
n = int(in_s.split('\n')[0])
stu = list(map(int, in_s.split('\n')[1].split()))
print(f"\n输入:\n{in_s}\n\n预期输出:0 3 0 0 7\n\n实际输出:{' '.join(map(str, [is_add(i) for i in stu]))}") # 用列表解析式解析每个学生还需刷题量,用jion()方法拼接输出。
'''for i in stu:
print(i, is_add(i))''' # 循环遍历轮询写法。