描述
对于一间公司来说,它成立之时所做的第一件事恐怕就是任命CEO了。之后,CEO就会开始雇用员工,也会有员工离职去别的公司。假设公司中的每一个员工(包括 CEO在内)都可以直接雇用新的员工,而公司中的所有员工(包括CEO)也都可能会跳槽离开,则某公司在成立一段时间之后的的组织结构如图1:
VonNeumann是公司的CEO,他直接雇用了两个人,分别是Tanenbaum和Dijkstra。在公司中,某员工的几个直接下属,他们的职位是由员工们的工龄决定的,在图中即表现为从从左至右职位越来越低,譬如Tanenbaum的职位就比Dijkstra要高。
当一个员工雇用了新的下属时,该下属在该员工雇佣的所有下属中,职位是最低的。假设VonNeumann又雇用了Shannon,则VonNeumann的三名下属职位从高到低分别是Tanenbaum、Dijkstra和Shannon。
当公司中的员工离职,则有两种情况。若他没有雇用任何下属,则他会被从公司的组织结构中拿掉。若他有直接的下属,则他的直接下属中职位较高的人,会升职并补上缺位。而该下属若也有下属,则他的下属中职位最高的,会补上他升值后空出的位子。以此类推,直到某个尚未雇用下属的员工升职。
假设图1中的Tanenbaum跳槽离开了,则Stallings会补上它的位置,而Knuth会补上Stallings的位置。图2展示了变化后的结果:(1) VonNeumann雇用了Shannon,(2) Tanenbaum跳槽。
输入
输入的第一行是 CEO 的姓名。题目中所有的人名的长度都在2-20之间,且由大小写字母、数字和短线(减号)组成。每个名字都包含至少一个大写和一个小写字母。
在第一行后会有很多行内容,他们由如下的规则构成:
- [老员工] hires [新员工]
- fire [老员工]
[老员工] 是已经在公司工作的人的名字,而[新员工]是即将被雇用的员工的名字。以上三种规则组成的内容可能会按照任何顺序出现。但公司中会至少有一名员工(CEO),且公司的规模最大不会超过 1000 人。
输出
对于每一个打印命令,按照如下规则输出当前公司的结构信息:
每一行包含一个人名
第一行是CEO的名字,从第一列开始
图3形式的结果,
会输出为图4
在每次print之后,输出一行60个字符的减号,整个输出中没有任何空行。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
char name[25];
struct node *successor; //接班人
struct node* peer;
}human;
human *top,*root,*poorguy,*above;
char er[25],ee[25];
void creathuman(human **p) //此处必须使用引用
{
*p=(human*)malloc(sizeof(human));
memset((*p)->name,'\0',25);
strcpy((*p)->name,ee);
(*p)->successor=(*p)->peer=NULL;
return;
}
int hire(human *p)
{
if(p!=NULL)
{
if(!strcmp(p->name,er))
{
if(p->successor==NULL)
{
creathuman(&p->successor);
return 1;
}
else
{
p=p->successor;
while(p->peer!=NULL) p=p->peer; //找到插入点
creathuman(&p->peer);
return 1;
}
}
else
{
if(hire(p->peer)) return 1;
if(hire(p->successor)) return 1;
return 0;
}
}
else return 0;
}
void print(human *p,int dep)
{
if(p==NULL) return;
else
{
for(int i=0;i<dep;++i) printf("+");
printf("%s\n",p->name);
print(p->successor,dep+1);
print(p->peer,dep);
}
}
int find(human *pp) //找他的下属里有没有要被开除的
{
human *p=pp->successor;
while(p!=NULL)
{
if(!strcmp(p->name,ee))
{
above=pp;
poorguy=p;
return 1;
}
else p=p->peer;
}
p=pp->successor;//没找到,找下属的下属
while(p!=NULL)
{
if(find(p)) return 1;
p=p->peer;
}
return 0;
}
void arrange(human *p)
{
if(p->successor->successor==NULL)
{
memset(p->name,'\0',25);
strcpy(p->name,p->successor->name);
p->successor=p->successor->peer;
return;
}
memset(p->name,'\0',25);
strcpy(p->name,p->successor->name);
arrange(p->successor);
}
void fire()
{
if(poorguy->successor==NULL) //被开除者没有下属
{
if(above->successor==poorguy)
{
above->successor=above->successor->peer;
return;
}
else
{
human *p=above->successor;
while(p->peer!=poorguy) p=p->peer;
p->peer=p->peer->peer;
}
}
else
{
arrange(poorguy);
}
}
int main(){
//老板
char name[25],operate[25];
memset(operate,'\0',25);
memset(name,'\0',25);
scanf("%s",name);
top=(human*)malloc(sizeof(human));
memset(top->name,'\0',25); //初始化
strcpy(top->name,name);
top->successor=top->peer=NULL;
root = (human*)malloc(sizeof(human));
root->successor=top;
root->peer=NULL;
//操作
while(scanf("%s",operate)!=EOF)
{
if(!strcmp(operate,"print"))
{
print(top,0);
for(int i=0;i<60;++i) printf("-");
printf("\n");
}
else if(!strcmp(operate,"fire"))
{
memset(er,'\0',25);
memset(ee,'\0',25);
scanf("%s",ee);
find(root);
fire(); //开除
}
else //hire
{
memset(er,'\0',25);
memset(ee,'\0',25);
strcpy(er,operate);
scanf("%s",operate);
scanf("%s",ee);
hire(top);
}
}
}