题目描述
现在我们需要查出一些作弊的问答社区中的ID,作弊有两种:1.A回答了B的问题,同时B回答了A的问题。那么A和B都是作弊。2.作弊ID用户A和作弊ID用户B同时回答了C的问题,那么C也是作弊。已知每个用户的ID是一串数字,一个问题可能有多个人回答。
输入描述:
每组数据第一行为总问题数N(N小于等于200000),第二行开始每行一个问题,第一个数字为提问人ID,第二个数字为回答人数,后面则为所有回答人的ID。(ID均为0-1000000的整数)
输出描述:
第一行为作弊ID数量,第二行开始为从小到大的每行一个作弊ID。
输入例子:
3 1 1 2 2 1 1 3 2 1 2
输出例子:
3 1 2 3
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
while(in.hasNext()){
int n=in.nextInt();//n为提问的总数
HashSet<Integer> request=new HashSet();//存放提问的所有人ID
HashMap<Integer,HashSet<Integer>> map=new HashMap();//存放提问的人ID和回答人ID的集合
for(int i=0;i<n;i++){//对n个问题进行搜集
int curID=in.nextInt();//当前提问人的ID
int ansCount=in.nextInt();//回答的人数
HashSet<Integer> set=new HashSet();//回答人ID的集合
for(int j=0;j<ansCount;j++){
set.add(in.nextInt());
}
request.add(curID);
if(!map.containsKey(curID)){//若map中还没有该curID
map.put(curID,set);
}else{//若已经有了该ID
map.get(curID).addAll(set);
}
}
//handle the first condition
TreeSet<Integer> result=new TreeSet();//存放结果,且排序了
for(int temp: request){
Set<Integer> tempSet=map.get(temp);
for(int num: tempSet){
if(map.containsKey(num)){
if(num!=temp){
Set<Integer> chkSet=map.get(num);
for(int num2: chkSet){
if(num2 == temp){
result.add(num);
result.add(temp);
//request.remove(num);foreach时使用了迭代器,不能更改容器结构
//request.remove(temp);
break;
}
}
}
}
}
}
//handle second
for(int temp: request){
int count=0;
Set<Integer> tempSet=map.get(temp);
for(int num: tempSet){
if(result.contains(num)){
count++;
}
if(count == 2){
result.add(temp);
//request.remove(request);
break;
}
}
}
System.out.println(result.size());
for(int i: result){
System.out.println(i);
}
}
in.close();
}
}