d365: 10336 - Rank the Languages

https://zerojudge.tw/ShowProblem?problemid=d365

你可能有注意到世界上有許多地區使用英語及西班牙語。現在我們就要來對世界上所有地區使用的語言作個排行榜。

你會給一個地圖,在上面會標示各地區以幾他們所使用的語言。請看以下的地圖:

ttuuttdd 
ttuuttdd 
uuttuudd 
uuttuudd

每個字元代表一種語言,並且區域被定義為同一個字元相連的地區。2個字元"相連"指的是該2字元有上、下、左、右四個方向鄰近的關係。所以在上圖中有3個區域說 t 語言,有3個區域說 u 語言,有1個區域說 d 語言。

你的任務就是要找出地圖中每種語言被說的區域數,並且按照一定的順序輸出。

範例輸入

2
4 8
ttuuttdd
ttuuttdd
uuttuudd
uuttuudd
9 9
bbbbbbbbb
aaaaaaaab
bbbbbbbab
baaaaacab
bacccccab
bacbbbcab
bacccccab
baaaaaaab
bbbbbbbbb

範例輸出

World #1
t: 3
u: 3
d: 1
World #2
b: 2
a: 1
c: 1

解題提示

如何從一個點擴散出去,搜尋四面八方的地圖,這項技能你已經學會了,那在這邊該如何使用呢?簡單的說就是對地圖中的每一格進行DFS搜尋,先記錄起始點的字元,假如說起始點是a,那接下來碰到的字元只要不是a都視為牆壁。拜訪過的地圖也記得做標記。


解答


#include<iostream>
using namespace std;

struct Coordinate{
    int x;
    int y;
};

int direct[4][2] = { 0,-1,
                    -1, 0,
                     0, 1,
                     1, 0};

bool order(char,int,char,int);

int main()
{
    char langMap[101][101]; //語言地圖

    //T:測資數量,H:地圖高度,W:地圖寬度
    int T,H,W;

    cin>>T; //輸入測資數量

    //對每組測資進行分析
    for(int count=1;count<=T;count++)
    {
        //mark的值為1代表已經處理的區域,0代表未處理,預設都為0
        bool mark[101][101]={0};

        cin>>H>>W; //輸入二維地圖的長寬

        for(int i=0;i<H;i++) //輸入二維地圖的內容
            cin>>langMap[i];

        Coordinate coord[10000];
        int num[26] = {0};

        //對地圖中的每一格進行DFS處理
        for(int i=0; i<H; i++)
            for(int j=0; j<W; j++)
            {
                if(!mark[i][j])//尚未被計算過
                {
                    char find = langMap[i][j]; //此格地圖為哪個字元
                    num[find - 'a']++; //將該字元出現過的數量+1
                    int top=0, tail=0;
                    coord[top].x = i;
                    coord[top].y = j;
                    top++;
                    mark[i][j] = true; //被處理過

                    //DFS搜尋開始
                    while(top>tail)
                    {

                        for(int s=0; s<4; s++)//s代表4個方向
                        {
                            int fx = coord[tail].x+direct[s][0];
                            int fy = coord[tail].y+direct[s][1];
                            //探索的這格地圖
                            //如果 沒超出地圖範圍 且 是沒被計算過的 且 跟我們想找的符號是一樣的
                            if(fx>-1&&fx<H&&fy>-1&&fy<W && !mark[fx][fy]&&langMap[fx][fy]==find)
                            {
                                //就處理把這格地圖
                                mark[fx][fy] = true;
                                coord[top].x = fx;
                                coord[top].y = fy;
                                top++;
                            }
                        }
                        tail++;
                    }

                }

                /*
                //每處理一個區塊,就印出已處理過的區域
                cout<<"("<<i<<","<<j<<")"<<endl;
                for(int o=0;o<H;o++)
                {
                    for(int p=0;p<W;p++)
                    {
                        cout<<mark[o][p];
                    }
                    cout<<endl;
                }
                */

            }

        char lan[26];
        int field[26];
        int c=0;
        for(int i=0; i<26; i++)
            if(num[i]>0)
            {
                lan[c] = i+'a'; //字元
                field[c] = num[i]; //字元區域的數量
                c++;
            }

        //排序答案順序,區外數越多的越前面,區塊數一樣多的時候,字母排序前面的調到前面
        for(int i=0; i<c;i++)
        {
            for(int j=i+1; j<c; j++)
            {
                if(order(lan[i],field[i],lan[j],field[j]))
                {
                    swap(lan[i],lan[j]);
                    swap(field[i],field[j]);
                }
            }
        }

        cout<<"World #"<<count<<endl;
        for(int i=c-1; i>-1; i--)
            cout<<lan[i]<<": "<<field[i]<<endl;

    }
}

bool order(char ac,int a,char bc,int b)
{
    if(a==b)
        return bc>ac;
    if(a>b)
        return true;
    else
        return false;
}

results matching ""

    No results matching ""