-
-
有N个人,各自有一个姓名和ID(别名)。每个人的姓名和ID都没有重复。这些人依次进入一间房间,然后可能会离开。过程中可以得到一些信息,告知在房间里的某个人的ID。你的任务是准确地确定每个人的ID。
输入描述 Input Description第一行是整数N,表示N个人,N<=20。
接下来的一行是N个人的ID,用一个空格分隔。
接下来的若干行是过程的记录:一个字母和一个字符串。字母是E、L或M中的一个。E表示进入房间,后面跟的字符串表示进来的人的姓名;L表示离开房间,后面跟的字符串表示离开的人的姓名;M表示回答询问,后面跟的字符串表示:当前用这个ID人在房间里面。
最后一行Q表示结束。
所有的姓名和ID都由不超过20个的小写字母组成。所有姓名都会在记录中出现。
一开始时,房间时空的。
输出描述 Output Description共N行,每行形如:“姓名:ID”,如果ID不能确定,输出???。
按照姓名的字典顺序输出。
样例输入 Sample Input7
bigman mangler sinbad fatman bigcheese frenchie capodicapo
E mugsy
E knuckles
M bigman
M mangler
L mugsy
E clyde
E bonnie
M bigman
M fatman
M frenchie
L clyde
M fatman
E ugati
M sinbad
E moriarty
E booth
Q
样例输出 Sample Outputbonnie:fatman
booth:???
clyde:frenchie
knuckles:bigman
moriarty:???
mugsy:mangler
ugati:sinbad
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<map>
- #include<set>
- using namespace std;
- int n;
- int line[30][30];
- int b[30],g[30];
- bool used[30];
- map<string,int>name;
- string na[30];
- map<string,int>id;
- string di[30];
- set<int>se;
- set<int>leave;
- bool vis[30];
- struct Node
- {
- string name,id;
- bool operator<(const Node& u)const
- {
- return name<u.name;
- }
- };
- Node p[30];
- int e=0;
- bool find(int x);
- bool check(int x);
- int main()
- {
- memset(b,0,sizeof(b));
- memset(g,0,sizeof(g));
- string str;
- char ch[2];
- scanf("%d",&n);
- for(int i=0;i<n;i++){
- cin>>str;
- id[str]=i+1;
- di[i+1]=str;
- leave.insert(i+1);
- }
- int o=1;
- for(int i=1;i<=n;i++){
- for(int j=1;j<=n;j++)
- line[i][j]=1;
- }
- while(~scanf("%s",ch)){
- if(ch[0]=='Q')
- break;
- cin>>str;
- if(ch[0]=='E'){
- if(name[str]==0){
- name[str]=o++;
- na[o-1]=str;
- }
- se.insert(name[str]);
- leave.erase(name[str]);
- }
- else if(ch[0]=='L'){
- leave.insert(name[str]);
- se.erase(name[str]);
- }
- else{
- int k=id[str];
- for(set<int>::iterator it=leave.begin();it!=leave.end();it++){
- line[*it][k]=0;
- }
- }
- }
- for(int i=1;i<=n;i++){
- memset(used,0,sizeof(used));
- find(i);
- }
- for(int i=1;i<=n;i++){
- memset(vis,0,sizeof(vis));
- memset(used,0,sizeof(used));
- if(check(i)){
- p[e].name=na[i];
- p[e++].id="???";
- }
- else{
- p[e].name=na[i];
- p[e].id=di[b[i]];
- e++;
- }
- }
- sort(p,p+e);
- for(int i=0;i<e;i++)
- cout<<p[i].name<<":"<<p[i].id<<endl;
- return 0;
- }
- bool find(int x)
- {
- for(int i=1;i<=n;i++){
- if(line[x][i]==1&&used[i]==0){
- used[i]=1;
- if(g[i]==0||find(g[i])){
- b[x]=i;
- g[i]=x;
- return true;
- }
- }
- }
- return false;
- }
- //判断x能不能有别的匹配
- bool check(int x)
- {
- if(vis[x]==1)//走出回路
- return true;
- vis[x]=1;
- for(int i=1;i<=n;i++){
- if(used[i]==0&&line[x][i]&&g[i]!=x){//不是原匹配
- used[i]=1;
- if(g[i]==0||check(g[i]))
- return true;
- }
- }
- return false;
- }
codevs姓名与id
最新推荐文章于 2022-09-10 13:29:45 发布