1. 程式人生 > 實用技巧 >L1-049 天梯賽座位分配

L1-049 天梯賽座位分配

L1-049天梯賽座位分配(20分)

天梯賽每年有大量參賽隊員,要保證同一所學校的所有隊員都不能相鄰,分配座位就成為一件比較麻煩的事情。為此我們制定如下策略:假設某賽場有 N 所學校參賽,第 i 所學校有 M[i] 支隊伍,每隊 10 位參賽選手。令每校選手排成一列縱隊,第 i+1 隊的選手排在第 i 隊選手之後。從第 1 所學校開始,各校的第 1 位隊員順次入座,然後是各校的第 2 位隊員…… 以此類推。如果最後只剩下 1 所學校的隊伍還沒有分配座位,則需要安排他們的隊員隔位就坐。本題就要求你編寫程式,自動為各校生成隊員的座位號,從 1 開始編號。

輸入格式:

輸入在一行中給出參賽的高校數 N (不超過100的正整數);第二行給出 N 個不超過10的正整數,其中第 i 個數對應第 i 所高校的參賽隊伍數,數字間以空格分隔。

輸出格式:

從第 1 所高校的第 1 支隊伍開始,順次輸出隊員的座位號。每隊佔一行,座位號間以 1 個空格分隔,行首尾不得有多餘空格。另外,每所高校的第一行按“#X”輸出該校的編號X,從 1 開始。

輸入樣例:

3
3 4 2

輸出樣例:

#1
1 4 7 10 13 16 19 22 25 28
31 34 37 40 43 46 49 52 55 58
61 63 65 67 69 71 73 75 77 79
#2
2 5 8 11 14 17 20 23 26 29
32 35 38 41 44 47 50 53 56 59
62 64 66 68 70 72 74 76 78 80
82 84 86 88 90 92 94 96 98 100
#3
3 6 9 12 15 18 21 24 27 30
33 36 39 42 45 48 51 54 57 60

567890

看了題目之後就直接開始寫,簡單思考一下,是一對10個人,然後開始排。那麼第一個學校應該是1,然後是1+N(N為學校個數);在沒有學校排完之前這個是沒有問題的,那麼我們可以先實現這部分的程式碼。

int N;

void F_L1_049(int j,int i,int * Uni) {
    int num_Stu = 1;
    int * uni = new int [N];
    for(int k = 0;k < N;k++)
        uni[k] = Uni[k] * 10;
        
    while(num_Stu <= Uni[i] * 10
) { int sum = 0; if(num_Stu % 10 == 0) cout<< j <<endl; else cout<< j <<" ";

// 控制條件

num_Stu++; } delete [] uni; } int main() { cin>>N; int * Uni = new int [N]; for(int i = 0;i < N;i++) cin>>Uni[i]; for(int i = 0;i < N;i++) { cout<<"#"<<i + 1<<endl; F_L2_049(i + 1, i, Uni); } delete [] Uni; return 0; }

那麼接下來我們就需要控制一下當有學校減少時,間隔的變化問題。我們統計學校的個數,來當做間隔數,這樣按道理是可行的。其次我們還需要注意當學校數目少於兩個的時候間隔數仍然應該為2,而不是更小的數字,此時就需要一個判斷。

for(int k = 0;k < N;k++) {if(uni[k] > 0)
        --uni[k];            
    sum += (int)(bool)uni[k];        
}
 
if(sum < 2)
    j += 2;
else
    j += sum;

那麼現在我們的程式碼是正確的嗎?顯然還是存在問題的。

是可以發現,當學校突然減小的那一瞬間,我們的程式時反應不過來的,也就是沒有正確的計算出當學校減少時的數字。

而由此我們可以根據很多的測試資料看出,當隊伍數目最大的學校出現的順序不同時,會出現不同的結果,當然會產生正確的,也有錯誤的。

根據我們的設定,當uni == 1 的時候,就是出現學校消失的時候,這個時候需要判斷sum的變化,而只有當這個消失的學校在目前正在分配座位的學校後面時sum才會增加,因此最後得到的控制條件是:

for(int k = 0;k < N;k++) {
    if(uni[k] == 1 && k > i)
        sum++;
    if(uni[k] > 0) {
        --uni[k];            
        sum += (int)(bool)uni[k];                    
    }
}
if(sum < 2)
    j += 2;
else
    j += sum;

完整程式碼:

//#include<bits/stdc++.h> 
#include <iostream>
#include <cstring>
#include <string>
#include <iomanip>        // 格式化輸入輸出 
#include <cmath>
#include <cstdlib> 
#include <vector>

using namespace std;

int N;

void F_L2_049(int j,int i,int * Uni) {    // 座位函式 
    int num_Stu = 1;    //  已分配有座位的人數 
    int * uni = new int [N];    // 每個學校的總人數 
    for(int k = 0;k < N;k++)
        uni[k] = Uni[k] * 10;

    while(num_Stu <= Uni[i] * 10) {
        int sum = 0;    // 下一個座位同上一個座位的間隔數 
        if(num_Stu % 10 == 0)
            cout<< j <<endl;
        else
            cout<< j <<" ";

        for(int k = 0;k < N;k++) {    // 控制條件 
            if(uni[k] == 1 && k > i)
                sum++;
            if(uni[k] > 0) {
                --uni[k];            
            sum += (int)(bool)uni[k];                    
            }
        }
        if(sum < 2)
            j += 2;
        else
            j += sum;                // 控制條件 
            
        num_Stu++;
    }
    delete [] uni;
}

int main()
{
    cin>>N;
    int * Uni = new int [N];    // 每個學校的隊伍個數 
    for(int i = 0;i < N;i++)
        cin>>Uni[i];
    for(int i = 0;i < N;i++) {
        cout<<"#"<<i + 1<<endl;
        F_L2_049(i + 1, i, Uni);    // 座位函式 
    }
    delete [] Uni;
    return 0;
} 
View Code

可百度參考他人思路;