zoukankan      html  css  js  c++  java
  • 2018牛客网暑期ACM多校训练营(第十场)J Rikka with Nickname(二分,字符串)

    链接:https://ac.nowcoder.com/acm/contest/148/J?&headNav=acm
    来源:牛客网

    Rikka with Nickname
    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld
    题目描述
    Sometimes you may want to write a sentence into your nickname like "lubenwei niubi". But how to change it into a single word? Connect them one by one like "lubenweiniubi" looks stupid.

    To generate a better nickname, Rikka designs a non-trivial algorithm to merge a string sequence s1...sn into a single string. The algorithm starts with s=s1 and merges s2...sn into s one by one. The result of merging t into s is the shortest string r which satisfies s is a prefix of r and t is a subsequence of r.(If there are still multiple candidates, take the lexicographic order smallest one.)
    链接:https://ac.nowcoder.com/acm/contest/148/J?&headNav=acm
    来源:牛客网

    For example, if we want to generate a nickname from "lubenwei niubi", we will merge "niubi" into "lubenwei", and the result is "lubenweiubi".

    Now, given a sentence s1...sn with n words, Rikka wants you to calculate the resulting nickname generated by this algorithm.
    输入描述:
    链接:https://ac.nowcoder.com/acm/contest/148/J?&headNav=acm
    来源:牛客网

    输出描述:
    For each testcase, output a single line with a single string, the result nickname.
    链接:https://ac.nowcoder.com/acm/contest/148/J?&headNav=acm
    来源:牛客网

    示例1
    输入
    复制
    2
    2
    lubenwei
    niubi
    3
    aa
    ab
    abb
    输出
    复制
    lubenweiubi
    aabb

    题意:

    思路:

    维护一个vector a[i] 数组,a[i]代表ans中字符i分别存在哪些位置。

    对于每一个新尝试加入的字符,我们去vector中二分查找尽可能靠前的位置,如果找不到就只能老老实实的加入到ans中。

    能找到的话,把位置赋值为last,在 下一次查找中使用。

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
    inline void getInt(int* p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    
    
    std::vector<int> v[50];
    string ans, str;
    int n;
    int main()
    {
        //freopen("D:\common_text\code_stream\in.txt","r",stdin);
        //freopen("D:\common_textcode_stream\out.txt","w",stdout);
    
        int t;
        gbtb;
        cin >> t;
        while (t--)
        {
            // MS0(f);
            for (char i = 'a'; i <= 'z'; ++i)
            {
                v[i - 'a'].clear();
            }
            cin >> n;
            ans = "";
            int last = -1;
            cin >> ans;
            rep(i, 0, sz(ans))
            {
                v[ans[i] - 'a'].push_back(i);
            }
            repd(i, 2, n)
            {
                cin >> str;
                int len = str.length();
                last = -1;
                repd(j, 0, len - 1)
                {
                    if (sz(v[str[j] - 'a']))
                    {
                        int id = lower_bound(ALL(v[str[j] - 'a']), last) - v[str[j] - 'a'].begin();
                        if (id == sz(v[str[j] - 'a']))
                        {
                            ans.push_back(str[j]);
                            v[str[j] - 'a'].push_back(sz(ans) - 1);
                            last = inf;
                        } else
                        {
                            last = v[str[j] - 'a'][id] + 1;
                        }
                    } else
                    {
                        ans.push_back(str[j]);
                        v[str[j] - 'a'].push_back(sz(ans) - 1);
                        last = inf;
                    }
                }
            }
            cout << ans << endl;
        }
    
    
    
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    C语言预处理
    C语言结构体对齐
    C语言共用体、大小端、枚举
    C语言内存分配方法。
    C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用
    C语言中函数的传入值与传出值
    #define与typedef在重定义类型中的区别
    宏定义在位运算中的运用
    wait函数
    exit()与_exit()区别
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11220038.html
Copyright © 2011-2022 走看看