『题解』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;
}
posted @ 2022-01-21 21:21  仙山有茗  阅读(60)  评论(0编辑  收藏  举报