zoukankan      html  css  js  c++  java
  • 【codeforces 508D】Tanya and Password

    【题目链接】:http://codeforces.com/problemset/problem/508/D

    【题意】

    给你一个字符的所有连续3个的子串;
    让你复原出原串;
    (包含小写、大写字母以及数字);

    【题解】

    相当于给你n条边;
    每条边的两端;
    一个点是由s[0]s[1]组成的;
    另一端是s[1]s[2]组成的;
    (用map很容易做hash..)
    然后让你求一个欧拉通路;
    即经过所有的边仅一次的路径(一笔画);
    有向图;
    可以先算出每个点的入度和出度;
    设入度和出度的差的点数为1的个数为cnt;
    则只有当cnt为2或cnt为0的时候有解;
    当cnt==2时,其中出度-入度==1的点作为起点,出度-入度==-1的点作终点;
    当cnt==0时,随便取个点当起点;
    然后做fleury算法就好;
    (求出来的是逆序的,倒一下就好)
    讲得比较好的
    ↓↓
    这里写图片描述
    这里写图片描述
    这里写图片描述
    看了上面的分析;
    可以知道;
    在搜一个点的时候,往前走的同时删边;
    然后一条路走到黑;
    把中间没有出度的点输出就好(倒序的);
    然后对于中间还有出度的点再一条道走到黑就好(肯定能回来的);
    然后重复上述步骤;
    得到倒序的欧拉路径;

    【Number Of WA

    0

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ms(x,y) memset(x,y,sizeof x)
    #define Open() freopen("F:\rush.txt","r",stdin)
    #define Close() ios::sync_with_stdio(0),cin.tie(0)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 2e5+100;
    
    int n,tot,in[N*2],out[N*2],f[N*2],s,t;
    char S[4];
    map <string,int> dic;
    string is[N*2];
    vector <int> G[N*2];
    stack <int> sta;
    string ans="";
    
    int ff(int x)
    {
        if (f[x]!=x)
            return f[x] = ff(f[x]);
        else
            return x;
    }
    
    void wujie()
    {
        cout <<"NO"<<endl;
        exit(0);
    }
    
    void dfs(int x)
    {
        while (G[x].size())
        {
            //cout << x << endl;
            sta.push(x);
            int y = G[x][G[x].size()-1];
            G[x].pop_back();
            x = y;
        }
        sta.push(x);
    }
    
    void oula(int s)
    {
        sta.push(s);
        int flag = 0;
        while (!sta.empty())
        {
            int x = sta.top();
            int bridge = (G[x].size()==0);
            sta.pop();
            if (!bridge)
            {
                dfs(x);
            }
            else
            {
                if (!flag)
                {
                    ans+=is[x][1];
                    ans+=is[x][0];
                    flag = 1;
                }
                else
                    ans+=is[x][0];
            }
        }
    }
    
    int main()
    {
        //Open();
        Close();//scanf,puts,printf not use
        //init??????
        cin >> n;
        string s1,s2;
        rep1(i,1,2*n)
            f[i] = i;
        rep1(i,1,n)
        {
            cin >> S;
            s1 = S[0];
            s1+=S[1];
            s2 = S[1];
            s2+=S[2];
            if (dic[s1]==0)
                tot++,dic[s1] = tot,is[tot] = s1;
            if (dic[s2]==0)
                tot++,dic[s2] = tot,is[tot] = s2;
            int x = dic[s1],y = dic[s2];
            in[y]++,out[x]++;
            G[x].pb(y);
            int r1 = ff(x),r2 = ff(y);
            if (r1!=r2)
                f[r1] = r2;
        }
        n = tot;
        int root = ff(1);
        rep1(i,1,tot)
            if (ff(i)!=root)
                wujie();
        int cnt = 0;
        rep1(i,1,n)
        {
            if (in[i]==out[i]) continue;
            cnt++;
            if (in[i]-out[i]==-1)
                s = i;
            else
                if (in[i]-out[i]==1)
                    t = i;
                else
                    wujie();
        }
        //cout << tot <<endl;
        //cout <<is[1]<<endl;
        //cout <<is[2]<<endl;
        //cout <<is[3]<<endl;
        //cout <<is[4]<<endl;
        //cout <<"s="<<s<<' '<<"t="<<t<<endl;
        //return 0;
        if ( (cnt==2 && s!=0 && t!=0) || (cnt==0))
        {
            cout <<"YES"<<endl;
            if (cnt==0) s = 1;
            oula(s);
            reverse(ans.begin(),ans.end());
            cout << ans << endl;
        }
        else
            wujie();
        return 0;
    }
    
  • 相关阅读:
    java实现第五届蓝桥杯出栈次序
    java实现第五届蓝桥杯年龄巧合
    java实现第五届蓝桥杯年龄巧合
    java实现第五届蓝桥杯年龄巧合
    java实现第五届蓝桥杯年龄巧合
    java实现第五届蓝桥杯年龄巧合
    Java使用RandomAccessFile读写文件
    Java 实现文件随机读写-RandomAccessFile
    NIO 中文乱码自我解决的简单DEMO
    NIO 中文乱码问题的解决代码实现
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626298.html
Copyright © 2011-2022 走看看