救濟金發放(uva 133)

2021-07-05 01:57:15 字數 1792 閱讀 4292

n個人占城一圈,逆時針編號為1~n.有兩個**,a從1開始逆時針數,b從n順時針開始。在每一輪中,**a數k個數就停下來,**b數m個就停下來(注意有可能連個**停在同乙個人上)。接下來被**選中的人離開隊伍。

輸入n,k,m輸出每輪裡被選中的人的編號(如果有兩個人)先輸出被a選中的)。注意:輸出的每個數應當恰好佔3列。

【分析】

仍然採用自頂向下的方法編寫程式,用乙個大小為0的陣列表示人站成的圈。為了避免人走之後移動陣列元素,用0表示離開隊伍的人,數數時跳過即可。主程式如下:

#include 

const int maxn = 25;

int n,k,m;

int a[maxn];

int go(int p, int d, int k);//數過k個人,開始位置p必須是數1時候的前乙個位置。

int main()

int left = n;

int pa = n-1, pb = 0;

int panext,pbnext;

while (left)

a[pa] = a[pb] = 0;//選到的人標記為0,下次遇到後跳過

if (left) printf(",");

}printf("\n");

}return 0;

} int go(int p, int d, int l) while(a[p] == 0);

}return p;

}

還有一種方法,不過顯得有點繁瑣:

#include 

using namespace std ;

const int maxn = 10000 ;

int queue1[maxn] , queue2[maxn] ;

void init( int n )

int find( int a , int arr , int begin , int end )

return pos ;

}

void change( int a , int pos , int end )

int main()

else

//找應該刪除的人,並且刪除

int pos = find( first , queue1 , front1 , rear1 ) ;

if( pos != -1 && pos > front1 )//pos < front1說明這個位置不在佇列裡

//每刪除乙個就要把隊尾指標給往回倒一

pos = find( second , queue1 , front1 , rear1 ) ;

if( pos != -1 && pos > front1 )

pos = find( first , queue2 , front2 , rear2 ) ;

if( pos != -1 && pos > front2 )

pos = find( second , queue2 , front2 , rear2 ) ;

if( pos != -1 && pos > front2 )

front1++ ; front2++ ;//隊首元素出隊

} if( count < n ) printf( ",%3d" , queue1[rear1] ) ;

cout << endl ;

} return 0 ;

}

ps:主要步驟我在後面都寫了注釋

UVa 133 救濟金發放

這題的話,我們首先對於移動函式可以知道,因為只是順逆的關係,也就是加一或者減一,所以我們每次移動的時候,都補上乙個小於n的最大整數,然後取模,這樣就不會有負數,而且加之後的結果不會超過2 n,所以我們取模的結果就是0到n 1,然後加上1就可以得到原位置了。題目中的逆時針就是加一,順時針就是減一。in...

救濟金發放UVa 133

紫書p82 例題4 3 n n 20 個人站成一圈,逆時針依次編號為1 n。有兩個 a從1開始逆時針數,b從n開始順時針數。在每一輪中,a數k個就停下來,b數m個就停下來 注意有可能兩個 停在同乙個人上 接下來被 選中的人 1個或2個 離開隊伍。輸入n,k,m輸出每輪中被選中的人的編號 如果有兩個人...

UVA133救濟金發放

題目 n n 20 個人站成一圈,逆時針編號為1 n。有兩個 a從1開始逆時針數,b從n開始順時針數。在每一輪中,a數k個就停下來,b數m個就停下來 注意有可能兩個 停在同乙個人上 接下來被 選中的人 1個或者2個 離開隊伍。輸入n,k,m輸出每輪裡被選中的人的編號 如果有兩個人,先輸出被a選中的 ...