困獸之鬥--樂視2017暑期實習生筆試題(二)

經過深思熟慮之後,小賤君打算去M國闖一闖,那是一個古老的東方國度,傳說有很多高階魔法師,他想成爲一名偉大的魔法師,將來征服星辰大海。
經過千辛萬苦,小賤君終於來到了M國,不幸的是剛進城門小賤君就被M國的守城士兵困在了一種叫做“困獸之鬥”的陣法之中。
士兵對小賤君說:“看到漂浮在你身邊的寶石了嗎?彩虹連接的兩顆寶石可以任意交換位置,你需要通過一系列交換後使得寶石組成的字符串的字典序最小。若不能破陣,那還是請回吧!”
小賤君觀察了一下週圍的寶石,只見每顆寶石上標有一個小寫字母,而且有一些寶石上通過彩虹與其他寶石相連。
琢磨了半天,他終於搞懂了這個陣法的意思:
若寶石系列爲:dcba
其中有兩道彩虹,分別是(0,1),(1,2),代表第一個位置上的寶石可以和第二個位置上的寶石互換,第二個位置上的寶石可以和第三個位置上的寶石互換,最終可以得到字典序最小的寶石系列:bcda。
作爲小賤君的死黨,你有什麼方法幫助他破陣嗎?

輸入描述:

輸入包含多組測試數據。 對於每組測試數據: 字符串s --- 代表寶石序列 n --- 代表有n條彩虹 接下來n行,每行兩個數ai,bi --- 表示ai和bi由一條彩虹相連。 保證: 1<=s的長度<=10000 1<=n<=10000 且輸入數據均合法。



輸出描述:

對於每組數據,輸出一個字符串


輸入例子:
dcba
2
0 1
1 2
hellonowcoder
4
0 1
1 4
2 5
2 3

輸出例子:
bcda
ehllonowco
方法一:

/******************************************
*@time 2016/08/27   20:58
*@place dhu.13f.5005
*description    並查集+選擇排序
***************************************/
#include<cstdio>
#include<cstring>
#include<map>
#include<iostream>
using namespace std;
int Union[10001];
int find_Root(int node)//找到根節點
{
     int tmp=node;
    while(tmp!=Union[tmp])
    {
        tmp=Union[tmp];
    }
    Union[node]=tmp;//此處爲優化,縮短查找距離
    return tmp;
}
void creat_Tree(int be,int en)//創建並查集
{
    be=find_Root(be);
    en=find_Root(en);
    if(en!=be)
    {
        if(en>be)
        {
            Union[be]=en;
        }
        else
        Union[en]=be;
    }
}
void init(int num_Of_Nodes)
{
    for(int i=0;i<num_Of_Nodes;i++)
    {
        Union[i]=i;
    }
}
int main()
{
    char str[10001];
    while(scanf(" %s",str)!=EOF)
    {

        int num_Of_Routes;
        scanf("%d",&num_Of_Routes);
        int num_Of_Nodes=strlen(str);
        init(num_Of_Nodes);
        for(int i=0;i<num_Of_Routes;i++)
        {
            int be;
            int en;
            scanf("%d %d",&be,&en);
            creat_Tree(be,en);
        }
        for(int i=0;i<num_Of_Nodes-1;i++)//選擇排序
        {
            for(int j=i+1;j<num_Of_Nodes;j++)
            {
                if(find_Root(i)==find_Root(j)&&str[i]>str[j])//如果點在同一棵樹中,那麼他們就可以交換
                {
                  char t=str[i];
                  str[i]=str[j];
                  str[j]=t;
                }
            }
        }
        printf("%s\n",str);
    }
    return 0;
}


方法二:

/******************************************
*@time 2016/08/27   20:58
*@place dhu.13f.5005
*description    並查集
***************************************/
#include<cstdio>
#include<map>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int Union[10001];//儲存並查集
int find_Root(int node)//找到根節點
{
     int tmp=node;
    while(tmp!=Union[tmp])
    {
        tmp=Union[tmp];
    }
    Union[node]=tmp;//此處爲優化,縮短查找距離
    return tmp;
}
void creat_Tree(int be,int en)//創建並查集
{
    be=find_Root(be);
    en=find_Root(en);
    if(be!=en)
    {
        Union[en]=be;
    }
}
void inti(int num_Of_Nodes)//初始化
{
    for(int i=0;i<num_Of_Nodes;i++)
    {
        Union[i]=i;
    }
}
int main()
{
    char str[10001];
    while(scanf(" %s",str)!=EOF)
    {
        int num_Of_Routes;
        scanf("%d",&num_Of_Routes);//彩虹數目

        int num_Of_Nodes=strlen(str);//字符數
        inti(num_Of_Nodes);

        for(int i=0;i<num_Of_Routes;i++)
        {
            int be;
            int en;
            scanf("%d %d",&be,&en);
            creat_Tree(be,en);
        }
        map<int,vector<int> > trees;//將每棵樹的所點的下標儲存在一個Vector中
        map<int,vector<char> > strs;//將每棵樹的所點的內容儲存在一個Vector中
        for(int i=0;i<num_Of_Nodes;i++)
        {
            int root=find_Root(i);
            trees[root].push_back(i);
            strs[root].push_back(str[i]);
        }

        for(int i=0;i<trees.size();i++)
        {
            sort(trees[i].begin(),trees[i].end());//排序,使下標從小到大 排列
            sort(strs[i].begin(),strs[i].end());//字符排序
        }
        for(int i=0;i<trees.size();i++)//將排行序的字符插入到字符串中
        {
            for(int j=0;j<trees[i].size();j++)
            {
                str[trees[i][j]]=strs[i][j];
            }
        }
        printf("%s\n",str);
    }
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章