最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實現(xiàn)貪心算法(Greedy?Algorithm)的應(yīng)用場景示例

 更新時間:2025年11月22日 16:52:48   作者:MzKyle  
貪心算法是一種通過每一步選擇當前最優(yōu)解來推動全局最優(yōu)的啟發(fā)式算法,它適用于滿足貪心選擇性質(zhì)和最優(yōu)子結(jié)構(gòu)的問題,但并不總是能找到全局最優(yōu)解,貪心算法的關(guān)鍵在于設(shè)計正確的策略并證明其有效性,應(yīng)用范圍廣泛,包括資源調(diào)度、編碼壓縮、路徑規(guī)劃和網(wǎng)絡(luò)優(yōu)化等

在計算機科學和數(shù)學優(yōu)化領(lǐng)域,算法的選擇往往決定了問題解決的效率和質(zhì)量。作為一名后端開發(fā)者,掌握各種算法及其適用場景是提升代碼質(zhì)量和性能的關(guān)鍵。貪心算法作為一種直觀且在特定問題上高效的解決方案,在實際開發(fā)中有著廣泛的應(yīng)用。

貪心算法的核心思想是"貪婪"地選擇當前看起來最優(yōu)的解決方案,而不考慮全局。這種方法在某些問題上能夠得到全局最優(yōu)解,但在另一些問題上可能只能得到局部最優(yōu)解。理解貪心算法的工作原理、適用條件和局限性,對于我們正確選擇和應(yīng)用算法至關(guān)重要。

一、貪心算法的核心定義與本質(zhì)

貪心算法是一種在每一步選擇中都采取當前狀態(tài)下最優(yōu)(即局部最優(yōu))的選擇,以期最終獲得全局最優(yōu)解的啟發(fā)式算法。其核心思想可概括為:“走一步看一步,每步都選最好的,不回頭”。

與動態(tài)規(guī)劃(DP)需要存儲子問題的最優(yōu)解并回溯不同,貪心算法不依賴歷史決策——它通過每一步的局部最優(yōu)積累,直接推導全局最優(yōu)。這種“短視”的特性使其實現(xiàn)簡單、效率極高,但也決定了它并非適用于所有問題,必須滿足嚴格的前提條件。

二、貪心算法的適用條件

判斷一個問題能否用貪心算法解決,必須同時滿足以下兩個核心性質(zhì),缺一不可:

1. 貪心選擇性質(zhì)

每一步的局部最優(yōu)選擇,能夠?qū)蛉肿顑?yōu)解。即:在選擇當前最優(yōu)解時,不需要考慮后續(xù)的決策,其選擇結(jié)果不會影響后續(xù)子問題的最優(yōu)性。

  • 示例:活動選擇問題中,“選擇最早結(jié)束的活動”這一局部最優(yōu)選擇,能為后續(xù)留下更多時間選擇其他活動,最終導向全局最優(yōu)(最多活動數(shù))。
  • 反例:0-1背包問題中,“選擇價值密度最高的物品”無法保證全局最優(yōu)(可能因剩余空間無法容納其他高價值物品,導致總價值更低)。

2. 最優(yōu)子結(jié)構(gòu)性質(zhì)

全局最優(yōu)解中必然包含其子問題的最優(yōu)解。即:問題的最優(yōu)解可以分解為若干個子問題的最優(yōu)解的組合。

  • 示例:Dijkstra算法中,“從源點到節(jié)點v的最短路徑”必然包含“從源點到路徑上某中間節(jié)點u的最短路徑”——若存在更短的源點→u路徑,替換后可得到更短的源點→v路徑,與全局最優(yōu)矛盾。

3. 經(jīng)典反例:錯誤的貪心策略

以“找零錢問題”為例:
若硬幣面額為[1,3,4],需找6元。直覺貪心策略(選最大面額優(yōu)先)會得到4+1+1=6(3枚硬幣),但最優(yōu)解是3+3=6(2枚硬幣)。此時“最大面額優(yōu)先”的貪心策略不滿足“貪心選擇性質(zhì)”,導致全局最優(yōu)失效。

三、貪心算法的解題步驟

使用貪心算法解決問題需遵循固定流程,核心是策略設(shè)計正確性證明

  1. 問題建模:將實際問題抽象為“選擇問題”,明確目標函數(shù)(如“最多活動數(shù)”“最短路徑和”)和約束條件(如“活動不沖突”“邊權(quán)非負”)。
  2. 設(shè)計貪心策略:確定每一步如何選擇“局部最優(yōu)”。常見策略包括:按結(jié)束時間排序、按價值密度排序、按邊權(quán)排序等。
  3. 證明策略正確性:通過數(shù)學歸納法或反證法,驗證策略滿足“貪心選擇性質(zhì)”和“最優(yōu)子結(jié)構(gòu)”。
  4. 編碼實現(xiàn):根據(jù)策略選擇合適的數(shù)據(jù)結(jié)構(gòu)(如排序、優(yōu)先隊列、并查集),處理邊界情況(如空輸入、極端值)。
  5. 測試優(yōu)化:驗證結(jié)果正確性,優(yōu)化時間復(fù)雜度(如用快排替代冒泡排序)。

四、經(jīng)典問題與C++實現(xiàn)

貪心算法的應(yīng)用場景高度集中,以下為4類核心問題的詳細實現(xiàn):

1. 活動選擇問題(最多不沖突活動)

問題描述

給定n個活動,每個活動有開始時間start[i]和結(jié)束時間end[i],選擇最多不重疊的活動集合。

貪心策略

按活動的結(jié)束時間升序排序,優(yōu)先選擇最早結(jié)束的活動——該選擇能為后續(xù)活動預(yù)留最多時間,最大化總活動數(shù)。

C++實現(xiàn)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 定義活動結(jié)構(gòu)體
struct Activity {
    int start;  // 開始時間
    int end;    // 結(jié)束時間
};

// 排序規(guī)則:按結(jié)束時間升序
bool compare(const Activity& a, const Activity& b) {
    return a.end < b.end;
}

// 選擇最多不沖突活動
vector<Activity> selectMaxActivities(vector<Activity>& activities) {
    vector<Activity> result;
    if (activities.empty()) return result;

    // 1. 按結(jié)束時間排序
    sort(activities.begin(), activities.end(), compare);

    // 2. 選擇第一個活動(最早結(jié)束)
    result.push_back(activities[0]);
    int lastEnd = activities[0].end;

    // 3. 遍歷后續(xù)活動,選擇不沖突的(開始時間>=上一個結(jié)束時間)
    for (int i = 1; i < activities.size(); i++) {
        if (activities[i].start >= lastEnd) {
            result.push_back(activities[i]);
            lastEnd = activities[i].end;  // 更新最后一個活動的結(jié)束時間
        }
    }
    return result;
}

int main() {
    vector<Activity> activities = {
        {1, 4}, {3, 5}, {0, 6}, {5, 7}, {3, 9}, {5, 9}, {6, 10}, {8, 11}, {8, 12}, {2, 14}, {12, 16}
    };

    vector<Activity> selected = selectMaxActivities(activities);

    // 輸出結(jié)果
    cout << "選擇的活動(開始時間, 結(jié)束時間):" << endl;
    for (auto& act : selected) {
        cout << "(" << act.start << ", " << act.end << ")" << endl;
    }
    cout << "最多可選擇 " << selected.size() << " 個活動" << endl;
    return 0;
}

輸出結(jié)果

選擇的活動(開始時間, 結(jié)束時間):
(1, 4)
(5, 7)
(8, 11)
(12, 16)
最多可選擇 4 個活動

2. 哈夫曼編碼(最優(yōu)前綴編碼)

問題描述

給定字符的頻率分布(如a:5, b:9, c:12, d:13),構(gòu)造前綴編碼(無編碼是另一編碼的前綴),使總編碼長度(頻率×編碼長度之和)最小。

貪心策略

  1. 構(gòu)建最小堆(優(yōu)先隊列),存儲所有字符的頻率;
  2. 每次取出兩個頻率最小的節(jié)點,合并為一個新節(jié)點(頻率為兩節(jié)點之和);
  3. 將新節(jié)點入堆,重復(fù)步驟2,直到堆中只剩一個節(jié)點(哈夫曼樹的根);
  4. 樹的左分支記為0,右分支記為1,葉子節(jié)點的路徑即為對應(yīng)字符的編碼。

C++實現(xiàn)

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

// 計算哈夫曼編碼的總長度
int huffmanCodeTotalLength(const vector<int>& frequencies) {
    // 最小堆:priority_queue<Type, Container, Compare>
    priority_queue<int, vector<int>, greater<int>> minHeap;

    // 1. 將所有頻率入堆
    for (int freq : frequencies) {
        minHeap.push(freq);
    }

    int totalLength = 0;  // 總編碼長度

    // 2. 合并節(jié)點,直到堆中只剩1個節(jié)點
    while (minHeap.size() > 1) {
        // 取出兩個最小頻率
        int first = minHeap.top();
        minHeap.pop();
        int second = minHeap.top();
        minHeap.pop();

        // 合并后的新節(jié)點頻率
        int merged = first + second;
        totalLength += merged;  // 合并節(jié)點的頻率即編碼長度貢獻

        // 新節(jié)點入堆
        minHeap.push(merged);
    }

    return totalLength;
}

int main() {
    // 字符頻率:a:5, b:9, c:12, d:13, e:16, f:45
    vector<int> frequencies = {5, 9, 12, 13, 16, 45};

    int total = huffmanCodeTotalLength(frequencies);
    cout << "哈夫曼編碼的總長度:" << total << endl;  // 輸出:224
    return 0;
}

原理說明

總長度224的計算邏輯:
合并過程為5+9=14(貢獻14)→12+13=25(貢獻25)→14+16=30(貢獻30)→25+30=55(貢獻55)→45+55=100(貢獻100),總和14+25+30+55+100=224。

3. Dijkstra算法(單源最短路徑)

問題描述

帶非負權(quán)的無向/有向圖中,找到從源點S到所有其他節(jié)點的最短路徑長度。

貪心策略

  1. dist[]數(shù)組記錄源點到各節(jié)點的當前最短距離(初始為INF,dist[S]=0);
  2. 構(gòu)建最小堆,存儲(當前最短距離,節(jié)點),初始將(0, S)入堆;
  3. 每次取出堆頂節(jié)點u(當前距離源點最近的未確定節(jié)點),標記為“已確定”;
  4. 遍歷u的所有鄰接節(jié)點v,執(zhí)行松弛操作:若dist[v] > dist[u] + 邊權(quán)w,則更新dist[v],并將(dist[v], v)入堆;
  5. 重復(fù)步驟3-4,直到堆為空。

C++實現(xiàn)

#include <iostream>
#include <vector>
#include <queue>
#include <climits>
#include <stdexcept>  // 用于邊界校驗異常
using namespace std;

const int INF = INT_MAX;

vector<int> dijkstra(int n, int source, const vector<vector<pair<int, int>>>& adj) {
    // 邊界校驗:源點合法性
    if (source < 0 || source >= n) {
        throw invalid_argument("源點超出節(jié)點范圍!");
    }

    vector<int> dist(n, INF);
    dist[source] = 0;

    // 最小堆:(當前距離, 節(jié)點)
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> minHeap;
    minHeap.push({0, source});

    while (!minHeap.empty()) {
        auto [currentDist, u] = minHeap.top();  // C++17結(jié)構(gòu)化綁定
        minHeap.pop();

         if (currentDist > dist[u]) continue;

        // 遍歷u的所有鄰接節(jié)點
        for (auto [v, w] : adj[u]) {
            // 松弛操作:更新dist[v]
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                minHeap.push({dist[v], v});
            }
        }
    }

    return dist;
}

int main() {
    int n = 6;  // 節(jié)點數(shù)(0~5)
    vector<vector<pair<int, int>>> adj(n);  // 局部鄰接表,替代全局變量

    // 構(gòu)建圖(邊:u->v,權(quán)w)
    adj[0].emplace_back(1, 2);  // emplace_back比push_back更高效(直接構(gòu)造對象)
    adj[0].emplace_back(2, 4);
    adj[1].emplace_back(2, 1);
    adj[1].emplace_back(3, 7);
    adj[2].emplace_back(4, 3);
    adj[3].emplace_back(5, 1);
    adj[4].emplace_back(3, 2);
    adj[4].emplace_back(5, 5);

    int source = 0;
    try {
        vector<int> dist = dijkstra(n, source, adj);

        // 輸出正確結(jié)果
        cout << "源點 " << source << " 到各節(jié)點的最短距離:" << endl;
        for (int i = 0; i < n; ++i) {
            if (dist[i] == INF) {
                cout << "到節(jié)點 " << i << ":不可達" << endl;
            } else {
                cout << "到節(jié)點 " << i << ":" << dist[i] << endl;
            }
        }
    } catch (const invalid_argument& e) {
        // 捕獲邊界校驗異常
        cerr << "錯誤:" << e.what() << endl;
        return 1;
    }

    return 0;
}

輸出結(jié)果

源點 0 到各節(jié)點的最短距離:
到節(jié)點 0:0
到節(jié)點 1:2
到節(jié)點 2:3(0→1→2)
到節(jié)點 3:8(0→1→2→4→3)
到節(jié)點 4:6(0→1→2→4)
到節(jié)點 5:9(0→1→2→4→3→5)

4. Kruskal算法(最小生成樹)

問題描述

無向帶權(quán)圖中,找到一棵連接所有節(jié)點、總邊權(quán)和最小的生成樹(Minimum Spanning Tree, MST)。

貪心策略

  1. 將所有邊按權(quán)值升序排序;
  2. 并查集(Union-Find) 維護已選節(jié)點的連通性;
  3. 遍歷排序后的邊,若邊的兩個端點屬于不同連通分量(不構(gòu)成環(huán)),則將該邊加入MST,并合并兩個連通分量;
  4. 重復(fù)步驟3,直到MST包含n-1條邊(n為節(jié)點數(shù))。

C++實現(xiàn)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 定義邊結(jié)構(gòu)體
struct Edge {
    int u;      // 起點
    int v;      // 終點
    int weight; // 邊權(quán)
};

// 并查集(Union-Find):維護連通分量
class UnionFind {
private:
    vector<int> parent;  // 父節(jié)點
    vector<int> rank;    // 秩(用于路徑壓縮優(yōu)化)
public:
    UnionFind(int n) {
        parent.resize(n);
        rank.resize(n, 0);
        for (int i = 0; i < n; i++) {
            parent[i] = i;  // 初始父節(jié)點為自身
        }
    }

    // 查找根節(jié)點(路徑壓縮)
    int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);  // 遞歸壓縮路徑
        }
        return parent[x];
    }

    // 合并兩個連通分量(按秩合并)
    bool unite(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);

        if (rootX == rootY) return false;  // 已在同一分量

        // 秩小的樹合并到秩大的樹
        if (rank[rootX] < rank[rootY]) {
            parent[rootX] = rootY;
        } else {
            parent[rootY] = rootX;
            if (rank[rootX] == rank[rootY]) {
                rank[rootX]++;
            }
        }
        return true;
    }
};

// Kruskal算法:返回MST的總邊權(quán)
int kruskal(int n, vector<Edge>& edges) {
    // 1. 按邊權(quán)升序排序
    sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {
        return a.weight < b.weight;
    });

    UnionFind uf(n);
    int mstTotal = 0;  // MST總邊權(quán)
    int edgeCount = 0; // 已選邊數(shù)

    // 2. 遍歷邊,選擇不構(gòu)成環(huán)的邊
    for (auto& edge : edges) {
        if (uf.unite(edge.u, edge.v)) {
            mstTotal += edge.weight;
            edgeCount++;

            // MST需n-1條邊,提前退出
            if (edgeCount == n - 1) break;
        }
    }

    // 若邊數(shù)不足n-1,說明圖不連通
    return (edgeCount == n - 1) ? mstTotal : -1;
}

int main() {
    int n = 5;  // 節(jié)點數(shù)(0~4)
    vector<Edge> edges = {
        {0, 1, 2}, {0, 3, 6}, {1, 2, 3}, {1, 3, 8}, {1, 4, 5},
        {2, 4, 7}, {3, 4, 9}
    };

    int mstTotal = kruskal(n, edges);
    if (mstTotal == -1) {
        cout << "圖不連通,無法構(gòu)建MST" << endl;
    } else {
        cout << "最小生成樹的總邊權(quán):" << mstTotal << endl;  // 輸出:16
    }
    return 0;
}

原理說明

MST的邊為(0,1,2)、(1,2,3)(1,4,5)、(0,3,6),總權(quán)2+3+5+6=16,覆蓋所有5個節(jié)點且無環(huán)。

五、貪心算法與動態(tài)規(guī)劃的對比

貪心與DP均依賴“最優(yōu)子結(jié)構(gòu)”,但核心差異在于子問題的處理方式

對比維度貪心算法(Greedy)動態(tài)規(guī)劃(DP)
核心思想局部最優(yōu)→全局最優(yōu),不回溯存儲子問題最優(yōu)解,回溯推導全局最優(yōu)
子問題處理不存儲子問題解,每步直接選最優(yōu)存儲子問題解(如dp數(shù)組),避免重復(fù)計算
適用場景滿足“貪心選擇性質(zhì)”的問題不滿足貪心選擇性質(zhì),但有最優(yōu)子結(jié)構(gòu)
時間復(fù)雜度低(通常O(nlogn),排序主導)較高(通常O(n²)或O(nm))
典型問題活動選擇、哈夫曼編碼、Dijkstra0-1背包、最長公共子序列、斐波那契
最優(yōu)解保證需證明策略正確性,否則不保證只要狀態(tài)轉(zhuǎn)移正確,必為全局最優(yōu)

六、貪心算法的優(yōu)缺點與應(yīng)用場景

1. 優(yōu)點

  • 實現(xiàn)簡單:無需復(fù)雜的狀態(tài)轉(zhuǎn)移或子問題存儲,代碼邏輯清晰;
  • 效率極高:時間復(fù)雜度多為O(nlogn)(排序)或O(MlogN)(優(yōu)先隊列),遠低于DP;
  • 空間緊湊:無需存儲子問題解,空間復(fù)雜度通常為O(n)。

2. 缺點

  • 適用范圍窄:僅能解決滿足“貪心選擇性質(zhì)”的問題,多數(shù)問題不適用;
  • 正確性難證:需嚴格證明策略的有效性,直覺性策略易出錯(如找零錢反例);
  • 無回溯機制:一旦選擇錯誤,無法修正,只能重新設(shè)計策略。

3. 實際應(yīng)用

  • 資源調(diào)度:CPU短作業(yè)優(yōu)先(SJF)調(diào)度、任務(wù)優(yōu)先級調(diào)度;
  • 編碼壓縮:哈夫曼編碼(用于ZIP、JPEG等格式);
  • 路徑規(guī)劃:Dijkstra算法(導航軟件核心算法之一);
  • 網(wǎng)絡(luò)優(yōu)化:Kruskal/Prim算法(構(gòu)建通信網(wǎng)絡(luò)最小成本拓撲)。

貪心算法是一種“高效但挑剔”的算法:它通過局部最優(yōu)的積累快速推導全局最優(yōu),但僅適用于滿足“貪心選擇性質(zhì)”和“最優(yōu)子結(jié)構(gòu)”的問題。掌握貪心算法的核心在于:

  1. 學會判斷問題是否符合貪心適用條件;
  2. 設(shè)計正確的貪心策略并證明其有效性;
  3. 熟練運用排序、優(yōu)先隊列、并查集等數(shù)據(jù)結(jié)構(gòu)實現(xiàn)策略。

七、總結(jié)

到此這篇關(guān)于C++實現(xiàn)貪心算法(Greedy Algorithm)的應(yīng)用場景示例的文章就介紹到這了,更多相關(guān)C++實現(xiàn)貪心算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言撲克牌游戲示例

    C語言撲克牌游戲示例

    大家好,本篇文章主要講的是C語言撲克牌游戲示例,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 深入解析C++的循環(huán)鏈表與雙向鏈表設(shè)計的API實現(xiàn)

    深入解析C++的循環(huán)鏈表與雙向鏈表設(shè)計的API實現(xiàn)

    這篇文章主要介紹了C++的循環(huán)鏈表與雙向鏈表設(shè)計的API實現(xiàn),文中的示例對于鏈表結(jié)點的操作起到了很好的說明作用,需要的朋友可以參考下
    2016-03-03
  • c++11多線程編程之std::async的介紹與實例

    c++11多線程編程之std::async的介紹與實例

    這篇文章主要給大家介紹了關(guān)于c++11多線程編程之std::async的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • C語言實現(xiàn)搶紅包程序代碼精簡版

    C語言實現(xiàn)搶紅包程序代碼精簡版

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)搶紅包程序代碼的精簡版,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 基于Matlab繪制洛倫茲吸引子相圖

    基于Matlab繪制洛倫茲吸引子相圖

    洛倫茲吸引子(Lorenz attractor)是由MIT大學的氣象學家Edward Lorenz在1963年給出的。本文將利用Matlab實現(xiàn)洛倫茲吸引子相圖的繪制,感興趣的可以了解一下
    2022-04-04
  • C++實現(xiàn)無重復(fù)字符的最長子串

    C++實現(xiàn)無重復(fù)字符的最長子串

    本文主要介紹了C++實現(xiàn)無重復(fù)字符的最長子串,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C++回溯算法之深度優(yōu)先搜索詳細介紹

    C++回溯算法之深度優(yōu)先搜索詳細介紹

    回溯在迷宮搜索中使用很常見,就是這條路走不通,然后返回前一個路口,繼續(xù)下一條路。回溯算法說白了就是窮舉法,下面讓我們一起來看看回溯算法中深度優(yōu)先搜索吧
    2023-01-01
  • Qt設(shè)計時鐘效果

    Qt設(shè)計時鐘效果

    這篇文章主要為大家詳細介紹了Qt設(shè)計時鐘效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C語言rand函數(shù)的應(yīng)用實例(隨機數(shù)的生成)

    C語言rand函數(shù)的應(yīng)用實例(隨機數(shù)的生成)

    在c語言中它為我們提供了一個函數(shù)rand,用它我們可以來生成隨機數(shù),而它產(chǎn)生的數(shù)的范圍在0~RAND_MAX之間,這篇文章主要介紹了C語言rand函數(shù)應(yīng)用(隨機數(shù)的生成)的相關(guān)資料,需要的朋友可以參考下
    2025-12-12
  • QT6中添加串口模塊SerialPort的實現(xiàn)

    QT6中添加串口模塊SerialPort的實現(xiàn)

    本文主要介紹了QT6中添加串口模塊SerialPort的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09

最新評論

临沧市| 常州市| 宁安市| 剑河县| 丰城市| 万山特区| 白山市| 荆州市| 竹溪县| 吴川市| 庆城县| 中卫市| 若尔盖县| 武清区| 巴里| 江都市| 汨罗市| 池州市| 衢州市| 康马县| 三台县| 崇义县| 平南县| 珲春市| 专栏| 灵山县| 诸暨市| 吐鲁番市| 东兰县| 土默特右旗| 丰顺县| 大石桥市| 巴马| 襄垣县| 丹阳市| 白朗县| 进贤县| 三穗县| 延庆县| 马鞍山市| 钦州市|