『题解』Luogu P4432 [COCI2017-2018#2] ZigZag
题目大意
Zig 和 Zag 正在玩文字游戏。 Zig 说了一个字母,而 Zag 说了一个以该字母开头的单词。但是这个词需要出现在给出的单词列表中,并且被是相同首字母中使用的次数最少的单词。如果单词的选择不明确(即相同首字母中使用的次数最少的单词不止一个),那么 Zag 会选择字典序较小的字母。输入保证对于每个 Zig 的字母,都有可以选择的单词。
假设有一个由 \(K\) 个不同的单词组成的列表和一个 Zig 给出的 \(N\) 个字母组成的列表。编写一个程序,根据输入,输出 Zag 在游戏过程中说出的 \(N\) 个单词。
思路
一道水水的排序题。
STLyyds,时间的话···一言难尽。
用到的 STL:
string
存放单词,替换字符数组,简单亿些。vector
用于存放当前所有单词,开二维。sort
用来排序。
我们读入时直接判断首字母,并插入对应的数组。把每个字母开头的单词都排序,排完序后输出,\(pos_i\) 表示第 \(i\) 个字母开头的单词输出到第几个了,每次输出都更新一下。
代码
#include <iostream> // string在<iostream>里就有,没必要引入<string>
#include <vector> // vector
#include <algorithm> // sort
using namespace std;
int main(){
int n,m,pos[26]={0}; // n和m不多解释,pos代表a数组中当前已经输出到哪了,输出一次更新一次。
vector<string> a[26]; // 存放单词,相当于二维数组。
cin >> n >> m;
for(int i=0; i<n; i++){ // 输入不多说。
string t;
cin >> t;
a[t[0]-'a'].push_back(t);
}
for(int i=0; i<26; i++) sort(a[i].begin(),a[i].end()); // 耗时主要在这里,排26次序。。。
for(int i=0; i<m; i++){
int t;
char c;
cin >> c; // 为了不多写一次getchar()读取换行符,偷个懒。
t=c-'a'; // 使用次数较多,所以再开一个变量,省时省力。
cout << a[t][pos[t]++] << endl; // 输出当前字母开头的第pos[t]个单词,顺便更新pos。
if(pos[t]>=a[t].size()) pos[t]=0; // 如果pos已经到最后一个单词了,就改为第一个单词,循环。
}
return 0;
}