PAT A1121 Damn Single (25) [map set hash]

题目

“Damn Single (单身狗)” is the Chinese nickname for someone who is being single. You are supposed to find those who are alone in a big party, so they can be taken care of.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (<=50000), the total number of couples. Then N lines of the couples follow, each gives a couple of ID’s which are 5-digit numbers (i.e. from 00000 to 99999). Afer the list of couples, there is a positive integer M (<=10000)
followed by M ID’s of the party guests. The numbers are separated by spaces. It is guaranteed that nobody is having bigamous marriage (重婚) or dangling with more than one companion.
Output Specification:
First print in a line the total number of lonely guests. Then in the next line, print their ID’s in increasing order. The numbers must be separated by exactly 1 space, and there must be no extra space at the end of the line.
Sample Input:
3
11111 22222
33333 44444
55555 66666
7
55555 44444 10000 88888 22222 11111 23333
Sample Output:
5
10000 23333 44444 55555 88888

题目解析

提供情侣名单,寻找party上所有单身参加的人

解题思路

  1. 将情侣数据散列,方便用一方找另一方。
  • 可以使用数组,下标对应id,value对应自己配偶
  • 可以使用map,key对应id,value对应自己配偶

注:因为id从00000开始,所以不管是map还是数组,value都必须初始为非0(如:-1),否则所有人的配偶默认为00000。(尽管本题中没有对这种情况的测试,不这样处理,可以全部ac)

  1. 遍历找出party中单身参加的人
    2.1 如果自己有配偶,并且配偶在名单中已出现过,将自己和配偶都标记为2(2-意为非单身参加party)
    2.2 如果自己没有配偶,或者配偶在名单中未出现过,将自己标记为1(1-意为单身参加party)

易错点

  1. 将所有人配偶错误默认初始化为00000
  2. 打印时,需要注意格式化,不足五位数的要前面补0

知识点

set遍历

#include <iostream>
#include<set>
using namespace std;
int main(){
    int numList[6]={1,2,2,3,3,3};
    //1.set add
    set<int> numSet;
    for(int i=0;i<6;i++)
    {
        //2.1insert into set
        numSet.insert(numList[i]);
    }
    //2.travese set
    for(set<int>::iterator it=numSet.begin() ;it!=numSet.end();it++)
    {
        cout<<*it<<" occurs "<<endl;
    }
    //3.set find useage

    int findNum=1;
    if(numSet.find(findNum)!=numSet.end())
    {
        cout<<"find num "<<findNum<<" in set"<<endl;
    }else{
        cout<<"do not find num in set"<<findNum<<endl;
    }
    //set delete useage
    int eraseReturn=numSet.erase(1);
    if(1==eraseReturn)
    {
          cout<<"erase num 1 success"<<endl;
    }else{
        cout<<"erase failed,erase num not in set"<<endl;
    }
    return 0;
}

map遍历

#include <iostream>
#include <map>
using namespace std;

int main(){
    map<int,int> m;
    for (int i = 0; i < 10; i++){
        m[i] = i*i;
    }
    map<int,int>::iterator iter;
    iter = m.begin();
    while(iter != m.end()){
        cout << iter->first << "-" << iter->second << endl;
        iter++;
    }
    for (iter = m.begin();iter != m.end(); iter++){
        cout << iter->first << "-" << iter->second << endl;
    }
    for(auto &it : m){
        cout << it.first << "-" << it.second <<endl;
    }
    return 0;
}

Code

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
map<int,int> kv,ts;
vector<int> ans;
int main(int argc,char * argv[]) {
	//初始化
	for(int i=0; i<=99999; i++)kv[i]=-1;
	int n,k,v,m,id;
	scanf("%d",&n);
	for(int i=0; i<n; i++) {
		scanf("%d %d",&k,&v);
		kv[k]=v;
		kv[v]=k;
	}
	scanf("%d",&m);
	for(int i=0; i<m; i++) {
		scanf("%d",&id);
		if(kv[id]==-1||ts[kv[id]]==0)ts[id]=1;//配偶没有出现过, 将自己置为1,后序若有自己配偶出现时,将1变为2,若没有,就一直为1,统计为单身
		else ts[id]=ts[kv[id]]=2; //配偶出现过,两人都置为2,不是单身
	}
	for(auto it = ts.begin(); it!=ts.end(); it++) {
		if(it->second==1)
			ans.push_back(it->first);
	}
	sort(ans.begin(),ans.end());
	printf("%d\n",ans.size());
	for(int i=0; i<ans.size(); i++) {
		if(i!=0)printf(" ");
		printf("%05d",ans[i]);
	}
	return 0;
}
posted @ 2020-05-09 21:55  JamieHou  阅读(119)  评论(0编辑  收藏  举报