UVA - 140 Bandwidth C++【從這一篇開始好好寫思路】

題目:https://odzkskevi.qnssl.com/889829830aaae78906451977015d8af0?v=1532315931

思路:

我發現我每次ac後就懶得寫思路了,所以這次一邊寫代碼一邊寫思路。

這題看了半天終於讀懂意思了。

這一段的意思相信大家都能讀懂。所以題目給我們的輸入是哪些字母互相之間有連線,這個連線的最長距離就是該字母的帶寬,所有字母帶寬的最大值就是該排列的帶寬。

  比如樣例,A:FB;B:GC;D:GC;F:AGH;E:HD,如果我們按照ABCDEFGH來排列的話,那麼帶寬是5。而答案A B C F G D H E排列帶寬是3,顯然後者更優。而這題就是讓我們尋找最優解。

所以……要怎麼尋找。我是在刷紫書,所以看題時不小心就看到了劉汝佳的分析= =他說枚舉全排列,然後剪枝。那就試試唄……全排列的話,紫書前幾頁有一個STL裏的next_permutation()函數,在algorithm中。我們先把所有排列枚舉一下,然後分別計算他們的帶寬。因爲帶寬是要取所有結點之間距離的最大值,所以如果這兩個結點直接距離已經超過上一個排列的帶寬的話,我們就可以剪枝。

ok思路就到這裏……我去寫寫看。不成的話再改,反正也不是直播23333

-----------居然ac了,我還以爲會T。

這題輸入挺麻煩的,我用map裏面套set,本來是套vector的,但是vector會重複,所以用set比較好,並且set還自動排序。每一個結點對應的結點都放在它的set裏。嘛,看代碼就知道了。調用起來用迭代器就行。然後再用一個set來統計一共幾個字母。

代碼:

#include<iostream>
#include<algorithm>
#include<map>
#include<cstdio>
#include<string>
#include<cstring>
#include<set>
#include<cmath>
using namespace std;
#define INF 100000

map<int,set<int> >m;
set<int> s;
int ss[200];

int main()
{
    char a[100];
    char g[10];
    while(scanf("%s",&a)&&a[0]!='#')
    {
        m.clear();
        s.clear();
        memset(ss,0,sizeof(ss));
        memset(g,0,sizeof(g));
        int cur=(int)a[0];
        s.insert(a[0]);
        for(int i=1;i<strlen(a);)
        {
            if(a[i]==':')i++;
            else if(a[i]==';'){
                i++;
                s.insert(a[i]);
                cur=(int)a[i];
                i++;
            }
            else {m[cur].insert(a[i]);m[a[i]].insert(cur);s.insert(a[i]);i++;}
        }
        int k=0;
        set<int>::iterator it;
        for(it=s.begin();it!=s.end();it++)
        {
            ss[k]=*it;
            k++;
        }
        sort(ss,ss+k);

        int id[200];
        int mmax=INF;
        do{
            memset(id,0,sizeof(id));
            for(int i=0;i<k;i++){
                id[ss[i]]=i;
            }
            int mo=-INF;
            for(int i=0;i<k;i++){
                int mm=-INF;
                if(!m[ss[i]].empty()){
                    set<int>::iterator it;
                    for(it=m[ss[i]].begin();it!=m[ss[i]].end();it++)
                    {
                        mm=max(mm,abs(id[*it]-id[ss[i]]));
                        if(mm>=mmax)break;
                    }
                }
                mo=max(mo,mm);
                if(mo>=mmax)break;
            }
            if(mo>=mmax)continue;
            else {
                mmax=mo;
                for(int i=0;i<k;i++){
                    g[i]=(char)ss[i];
                }
            }
        }while(next_permutation(ss,ss+k));
        for(int i=0;i<k;i++){
            cout<<g[i]<<" ";
        }
        cout<<"-> "<<mmax<<endl;
    }
    return 0;
}

 

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