歷屆試題 分考場


問題描述
  n個人參加某項特殊考試。
  為了公平,要求任何兩個認識的人不能分在同一個考場。
  求是少需要分幾個考場才能滿足條件。
輸入格式
  第一行,一個整數n(1<n<100),表示參加考試的人數。
  第二行,一個整數m,表示接下來有m行數據
  以下m行每行的格式為:兩個整數a,b,用空格分開 (1<=a,b<=n) 表示第a個人與第b個人認識。
輸出格式
  一行一個整數,表示最少分幾個考場。
樣例輸入
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
樣例輸出
4
樣例輸入
5
10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
樣例輸出
5
題目分析:
  模擬分考場的過程,搜索每一種可能就可以,要在合適的地方剪枝!!
  剪枝少了一個等號,直接導致有一組數據超時。
  大規模的數據,不要用vector,直接 多花內存模擬一個動態數組即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int m[105][105];
int n;//學生人數 
int t_t;//認識的關系數 
int set[105][105];//記錄每個班級的人 
int len[105];//記錄每個班級的長度 
int sum = 0;//記錄最小班級數 
void dfs(int t, int tt){
    if(tt >= sum)
        return;//剪枝 
    if(t == n + 1){
        sum = tt < sum ? tt : sum;
        return;//分班結束返回 
    }
    int i;
    for(i=1;i<=n;i++){
        if(len[i] == 0)
            break;//如果此班無人,直接分入此班 
        int flag = 1;
        for(int j=0;j<len[i];j++){
            if(m[t][set[i][j]] == 1){
                flag = 0;
                break;
            }
        }
        if(flag){
            set[i][len[i]++] = t;
            dfs(t + 1, tt);
            set[i][len[i]--] = t;//回溯 
        }
    }
    if(i != n + 1){
        //cout<<"開辟新空間"<<i<<endl;
        set[i][len[i]++] = t;
        dfs(t + 1, tt + 1);
        set[i][len[i]--] = t;//回溯 
    }
}
int main(){
    scanf("%d", &n);
    sum = n;
    scanf("%d", &t_t);
    for(int i=0;i<t_t;i++){
        int a,b;
        scanf("%d %d", &a, &b);
        m[a][b] = 1;
        m[b][a] = 1;
    }
    dfs(1, 0);
    cout<<sum;
    return 0;
}

還需磨練內功啊!爭取做到任何時候穩如老狗。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM