无可奈何花落去,似曾相识燕归来。
研究燕子随季节迁徙的科学家们,给一批燕子做了标记,每只被标记的燕子有一个独特的编号。等它们归来时,再根据标记检查有哪些燕子没有回来,同时有哪些燕子是从别处飞来的,身上带了别人家的标记。
输入首先给出飞走的燕子的信息:在第一行给出不超过 105 的正整数 N,随后 N 行,每行给出一只飞走的燕子的编号。题目保证编号不重复。
随后是飞回的燕子的信息,首先是一个不超过 105 的非负整数 M,随后 M 行,每行给出一只飞回的燕子的编号。题目保证编号不重复。
编号为长度不超过 8 的、由英文字母和数字组成的字符串。
首先输出没有回来的燕子的信息,格式为:
Missing: X
ID[1]
...
ID[X]
其中 X
为没有回来的燕子的数量,ID[i]
(i
= 1, ..., X
)为按字典序递增输出的这些燕子的编号。
然后输出新增燕子的信息,格式同上,只是把 Missing
换成 New
。
如果 X
为零,则对应情况下输出 All Back
(都回来了)或 All Known
(都认识)。
5
CN009
CN018
CN001
CN005
CN000
6
US981
CN018
CN000
AUS83
CN005
RU996
Missing: 2
CN001
CN009
New: 3
AUS83
RU996
US981
5
CN009
CN018
CN001
CN005
CN000
5
CN018
CN001
CN005
CN009
CN000
All Back
All Known
概述
这道题思路不难,只是要注意AC时间,如果是常规做法,后几个测试点可能会超时,这里采用数组计数,设置一个足够大(一定要足够大,否则会段错误)的整型数组,将旧燕子的编号分段,截取后面的数字作为数组下标储存,设置一个状态,这里设置为1,例如编号为CN001的燕子,数组状态为ch[1]=1,表示这只燕子放走了,处理完放走的燕子后,处理飞回的燕子。这里就不能采用数组法了,因为飞回的燕子编号千奇百怪的,用旧燕子标记判断其是否为新增燕子,如果不是,就将数组中旧燕子的状态改变即可,如果是就直接放到容器里,用sort函数进行字典序排序就行了。最后根据题目要求输出即可,注意当新增燕子为0时需要输出"All Known"。
#include
using namespace std;
int ch[100001000]; //储存飞走燕子信息
vector v3; //储存新飞来燕子信息
void huan(string s, int a) //处理每一只飞走燕子,储存信息
{
string z;
int k = 0;
z = s.substr(a, s.length() - a);
for (int i = 0; i < z.length(); i++)
{
k += (z[z.length() - i - 1] - '0') * pow(10, i);
}
ch[k] = 1;
}
int main()
{
int len = 0;
string biaoji; //飞走燕子编号中的英文字母
string jiu, s;
int miss = 0, New = 0, n, m, N;
cin >> n;
N = n;
int j = 1;
while (n)
{
cin >> jiu;
if (n == N) //因为飞走燕子编号英文字母都一样,所以求一次就好
{
for (int i = 0; i < jiu.length(); i++)
{
if (jiu[i] >= '0' && jiu[i] <= '9')
{
j = i;
break;
}
}
}
n--;
huan(jiu, j);
}
biaoji = jiu.substr(0, j);
len = jiu.length();
cin >> m;
while (m--)
{
cin >> s;
if (s.substr(0, j) == biaoji && (s[j] >= '0' && s[j] <= '9'))
{
string z;
int k = 0;
z = s.substr(j, s.length() - j);
for (int i = 0; i < z.length(); i++)
{
k += (z[z.length() - i - 1] - '0') * pow(10, i);
}
if (ch[k] == 1) //如果飞回的燕子是放走的燕子
{
ch[k] = 2;
miss++;
}
else //如果不是
{
v3.push_back(s);
New++;
}
}
else
{
v3.push_back(s);
New++;
}
}
miss = N - miss; //没回来的燕子数量
if (miss == 0 && New == 0)
{
cout << "All Back" << endl;
cout << "All Known";
}
else
{
if (miss != 0)
{
cout << "Missing: " << miss << endl;
int y = 0;
while (miss)
{
if (ch[y] == 1)
{
cout << biaoji;
cout << setw(len - j) << setfill('0') << y << endl; //根据编号长度前补零
miss--;
}
y++;
}
}
if (New != 0)
{
cout << "New: " << New << endl;
sort(v3.begin(), v3.end()); //将新增燕子进行字典序排列
for (int i = 0; i < v3.size(); i++)
{
cout << v3[i] << endl;
}
}
if (New == 0) //这一步别忘了,如果没有新增燕子,有两分的测试点
{
cout << "All Known";
}
}
}