题解:P13849 [CERC 2023] Equal Schedules

· · 题解

P13849 [CERC 2023] Equal Schedules

题目概括

有两个工作时间表,旧的和新的,每个表每行包含三个数据:起始时间 s、结束时间 e、员工名字 t

第一个表结尾以 ------ 结束,第二个表结尾以 ====== 结束。

问员工在新旧两个表之间工作时间的差异,增加输出带正号的数,减少输出带负号的数,没有任何员工有差异输出 No differences found.

思路

我们只需要记录每个人员的旧工作时长,再用新的工作时长减去,就可以得到变化的时长了。

而每个员工工作时长 time_i = e_i - s_i

实现思路

1.对于两个表

使用结构体数组记录每个员工的信息。

注意到表里会出现多次同一个员工,而员工数量最多只有 1000。所以我们只需要在每次读入时都遍历一遍(并不会超时)已有员工,如果名字相同则修改 time_i,否则将新员工信息加入结构体数组。

注意到每个表的结束都有终止标志,所以每行第一个读入的 a 应为 string 类型,如果不是终止符则转化回 int 类型。

2.对于旧表

每次修改 time_i 都加上读入的时长 ti

3.对于新表

每次修改 time_i 都减去读入的时长 ti

最后,排序后遍历所有员工。

int n,tot,cnt;

int tonumber(string a){ //字符串转数字 int x=0; for (int i=0;i<a.length();i++){ x*=10; x+=a[i]-'0'; } return x; }

struct people{ //结构体 int time; string name; }p[1005];

bool cmp(people a,people b){ //排序按照名字 return a.name<b.name; }

int main(){ string s,t; int e; //三个数据

while(1){       //旧表 
    cin >> s;
    if (s=="------")        //终止 
        break;
    cin >> e >> t;
    int ti=e-tonumber(s);       //时长 
    bool flag=1;
    for (int i=1;i<=tot;i++)        //遍历已有员工 
        if (t==p[i].name){      //重复 
            flag=0;
            p[i].time+=ti;
            break; 
        }
    if (flag){      //没重复 
        p[++tot].name=t;
        p[tot].time=ti;
    }
}

while(1){       //新表 
    cin >> s;
    if (s=="======")        //终止 
        break;
    cin >> e >> t;
    int ti=e-tonumber(s);       //时长 
    bool flag=1;
    for (int i=1;i<=tot;i++)        //遍历已有员工 
        if (t==p[i].name){      //重复 
            flag=0;
            p[i].time-=ti;
            break;
        }
    if (flag){      //没重复 
        p[++tot].name=t;
        p[tot].time-=ti;
    }
}

sort(p+1,p+tot+1,cmp);      //排序 

bool flag=0;
for (int i=1;i<=tot;i++)        //遍历所有员工 
    if (p[i].time!=0){
        flag=1;
        cout << p[i].name << " ";       //输出 
        if (p[i].time>0) 
            cout << -p[i].time;
        else
            cout << '+' << -p[i].time;
        cout << endl;
    }

if (!flag)      //没有区别 
    cout << "No differences found.";
return 0;

}


这里有个小细节,即使是旧表中没出现的员工也有可能出现在新表里,所以增改规则一致。