B. AquaMoon and Stolen String

题目链接:https://codeforces.com/contest/1546/problem/B

所用算法:

思维,字符串相关

题意:

先给定 n 个长度为 m 的字符串(n 为奇数),其中字符串两两一组(预先不知道哪两个是一组),有一个字符串是单独的,再给定 n-1 个字符串,这 n-1 个字符串是这样得到的:先在原来的 n 个字符串中将那个单独的字符串删去,然后对其余 n-1 个字符串按组进行字符交换,即同一组的两个字符串随机选取任意个位置进行字符互换,最后再将这 n-1 个字符串随机打乱顺序。要求找出那个单独的被删除的字符串。
q 次查询,每次查询给定 n,m 以及初始的 n 个字符串和后来的 n-1 个字符串,输出单独的被删除的那个字符串。

思路:

由于每个字符串的长度都为 m,我们可以按字符在字符串中的位置对字符串的字符进行统计,先对 1~m 位置统计原来的 n 个字符串在各个位置上每个字符各出现了多少次,再对后来的 n-1 个字符串进行相同的统计,对于每个位置,该位置上前一次统计减去后一次统计多出来的那个字符即为被删除的字符串在该位置的字符,因此对每个位置找到被删除字符串在该位置的字符,连接即可。

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int cnt[maxn][26]; //cnt[i][j]表示在i位置,j字符出现了多少次
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        memset(cnt, 0, sizeof(cnt));
        int n, m;
        cin >> n >> m;
        string s;
        for (int i = 0; i < n; i++) //原来的n个字符串
        {
            cin >> s;
            for (int j = 0; j < m; j++) //对每个位置统计原来的n个字符串在该位置的各个字符出现的次数
                cnt[j][s[j] - 'a']++;
        }
        for (int i = 0; i < n - 1; i++) //后来的n-1个字符串
        {
            cin >> s;
            for (int j = 0; j < m; j++) //对每个位置统计后来的n-1个字符串在该位置的各个字符出现的次数
                cnt[j][s[j] - 'a']--;
        }
        string ans = "";
        for (int i = 0; i < m; i++) //遍历位置
        {
            for (int j = 0; j < 26; j++) //遍历字符
            {
                //对每个位置的每个字符用原来的出现次数减去后来的出现次数,若不为0则说明被删除的字符串在该位置的字符是当前字符,加入到答案
                if (cnt[i][j])
                {
                    ans += ('a' + j);
                    break;
                }
            }
        }
        cout << ans << endl;
    }
}

总结:

相似题目:

posted @ 2021-07-16 14:37  Wajor  阅读(97)  评论(1)    收藏  举报