Code jam 2022 Round 1C Letter Blocks

https://codingcompetitions.withgoogle.com/codejam/round/0000000000877b42/0000000000afe6a1#analysis

一道复杂的字符串拼接模拟题。

可以考虑对每个字符串进行预处理。

如果在middle的字符在其他字符串中出现过,则impossible。

如果字符在其他字符串的middle中出现过,则impossible。

然后可以将字符串简化为X或XY类型,并用map记录。

同时注意,不能同时出现XY1和XY2,以及X1Y和X2Y类型。(因为这样则一定无法拼接)。

之后可以对首字符串进行选取选取规则为,若选取X1Y1类型,则不能存在剩余的X1类型以及X2X1类型,若选取X1类型,则不能存在X2X1类型。(因为如果存在,则必须放在其前面)。

选取首字符串后,则可以进行拼接,对X1Y1,先遍历Y1,再遍历Y1Y2。当选取完全部字符串就可以进行输出。

如果遍历选择后,如果新的结尾字符和旧的结尾字符相同,且没有选取完字符串,则接下来重新按选取首字符串的规则进行选取。

直到选取完全部字符串。

代码如下

复制代码
#include<bits/stdc++.h>
using namespace std;

int m_index = 0;

string cur_str;

void YD()
{
    m_index++;
    cur_str.clear();
    int n;
    cin >> n;
    vector<string> all_str(n);
    for (int i = 0; i < n; i++)
        cin >> all_str[i];
    bool vis[26] = {false};
    bool vis_mid[26] = { false };
    map<char, vector<int>> ch_index;
    map<char, vector<int>> start_index;
    map<char, vector<int>> end_index;
    for (int index = 0; index < n; index++)
    {
        auto &str = all_str[index];
        int nn = str.size();
        int i = 0, j = nn - 1;
        if (vis_mid[str[i] - 'A'])
        {
            cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl;
            return;
        }
        if (vis_mid[str[j] - 'A'])
        {
            cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl;
            return;
        }

        while (i < nn - 1 && str[i + 1] == str[i]) i++;
        while (j > 0 && str[j - 1] == str[j]) j--;
        if (j <= i)
        {
            vis[str[i]-'A'] = true;
            ch_index[str[i]].push_back(index);
            continue;
        }
        if (str[i] == str[j] && i < j)
        {
            cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl;
            return;
        }
        vis[str[i] - 'A'] = true;
        vis[str[j] - 'A'] = true;
        start_index[str[i]].push_back(index);
        if (start_index[str[i]].size() != 1)
        {
            cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl;
            return;
        }
        end_index[str[j]].push_back(index);
        if (end_index[str[j]].size() != 1)
        {
            cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl;
            return;
        }
        while (++i < j)
        {
            if (vis[str[i] - 'A'] && str[i] != str[i - 1])
            {
                cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl;
                return;
            }
            vis[str[i] - 'A'] = true;
            vis_mid[str[i] - 'A'] = true;
        }


    }
    int first = -1;
    for (auto &[ch, v_i] : start_index)
    {
        if (end_index.count(ch) == 0 && ch_index.count(ch) == 0)
        {
            first = v_i[0];
            break;
        }
    }
    if (first == -1)
    {
        for (auto &[ch, i] : ch_index)
        {
            if (end_index.count(ch) == 0)
            {
                first = i[0];
                break;
            }
        }
    }
    if (first == -1)
    {
        cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl;
        return;
    }
    vector<bool> vi(n, false);
    vi[first] = true;
    vector<int> res;
    res.push_back(first);
    char cur_end = all_str[first].back();
    while (res.size() < n)
    {
        char prev_end = cur_end;
        if (ch_index.count(cur_end))
        {
            for (auto ii : ch_index[cur_end])
            {
                if (vi[ii])
                {
                    continue;
                }
                else
                {
                    vi[ii] = true;
                    res.push_back(ii);
                }
            }
        }
        if (res.size() == n)
            break;
        if (start_index.count(cur_end))
        {
            for (auto ii : start_index[cur_end])
            {
                if (vi[ii])
                {
                    continue;
                }
                else
                {
                    vi[ii] = true;
                    res.push_back(ii);
                    cur_end = all_str[ii].back();
                }
            }
        }
        if (res.size() == n)
            break;
        if (cur_end == prev_end)
        {
            first = -1;
            for (auto &[ch, v_i] : start_index)
            {
                if (!vi[v_i[0]] && end_index.count(ch) == 0 && ch_index.count(ch) == 0)
                {
                    first = v_i[0];
                    break;
                }
            }
            if (first == -1)
            {
                for (auto &[ch, i] : ch_index)
                {
                    if (!vi[i[0]]&&end_index.count(ch) == 0)
                    {
                        first = i[0];
                        break;
                    }
                }
            }
            if (first == -1)
            {
                cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl;
                return;
            }
            vi[first] = true;
            res.push_back(first);
            cur_end = all_str[first].back();
        }
    }
    if (res.size() == n)
    {
        cout << "Case #" << m_index << ": ";
        for (auto i : res)
        {
            cout << all_str[i];
        }
        cout << endl;
    }

}
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        YD();
    }
}
View Code
复制代码

 

posted @   80k  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示