hiho一下 第147周 小Hi的烦恼
主要是参考了讨论区的方法。。。http://hihocoder.com/discuss/tag/hiho%E4%B8%80%E4%B8%8B%E7%AC%AC147%E5%91%A8
题目要求:
描述
小Hi从小的一大兴趣爱好就是学习,但是他发现尽管他认真学习,依旧有学神考的比他好。
小Hi在高中期间参加了市里的期末考试,一共五门:语文、数学、英语、物理、化学。
成绩出来之后,小Hi发现有些同学,所有科目都考的比他好,他很烦恼。所以他想知道所有科目都比自己名次靠前的同学的人数。
为了方便,可以认为不存在两个人某一门名次是相同的。
其他同学们也想知道有多少人全面碾压了他们,所以你需要对所有人输出答案。
解题方法提示
输入
第一行,一个正整数N(N <= 30000),表示人数。
接下来N行,每行五个整数,分别表示五门课依次的排名。
输出
输出共N行,每行一个整数,表示答案。
样例输入
4
1 1 2 2 1
2 3 3 3 2
3 2 1 1 3
4 4 4 4 4
实现代码(Java):
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Scanner;
public class HiHo147Week {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] nums = new int[n+1][5];
int[][] revNums = new int[n+1][5];
for(int i=1;i<=n;i++){
for(int j=0;j<5;j++){
nums[i][j] = sc.nextInt();
revNums[nums[i][j]][j]= i;
}
}
ArrayList<HashMap<Integer, BitSet>> list = new ArrayList<>();
for(int i=1;i<=n;i++){ // 从排名第二的人开始 才会有前一个人
for(int j=0;j<5;j++){
HashMap<Integer, BitSet> temp = new HashMap<>();
BitSet bitSet = new BitSet(n+1);
bitSet.set(revNums[i][j]);
if(i!=1){
temp = list.get(j);
bitSet.or(list.get(j).get(i-1));
}
temp.put(i, bitSet);
if(i==1){
list.add(temp);
}
}
}
// for(HashMap<Integer, BitSet> map:list){
// for(int key : map.keySet()){
// System.out.println("key:"+key+" value:"+map.get(key).toString());
// }
// }
for(int i=1;i<=n;i++){
BitSet ans = new BitSet(n+1);
ans.set(0, n+1, true);
for(int j=0;j<5;j++){
int yw = nums[i][j]; // 第i个人排名第nums[i][j];
if(yw == 1){
ans.set(0, n+1, false);
break;
}
BitSet bitSet = list.get(j).get(yw-1);
ans.and(bitSet);
// System.out.println(bitSet.toString());
}
System.out.println(ans.cardinality());
}
// System.out.println(bitSet.cardinality());
sc.close();
}
}