問題 : [出圈]
題目描述
設有n個人圍坐一圈並按順時針方向從1到n編號,從第1個人開始進行1到m的報數,報數到第個m人,此人出圈,再從他的下一個人重新開始1到m的報數,如此進行下去直到所剩下一人爲止。
輸入
輸入多行,每行2個數,分別表示n和m.
輸出
計算每一行中最後剩下這個人的編號.
樣例輸入
10 3
樣例輸出
4
可以通過兩種方法實現:
第一種:數組
方法:
數組中某處等零,即代表出圈(a[4]=0,即代表4的位置出圈)
先設一個數組a[1000]存放將要循環的數據n,然後設x用來判斷出圈了幾個數(當x=n-1即結束,僅剩一人未出圈)
再設i,y來不斷循環,
i用來判斷每一次循環到第幾個數,當i=m即表示報一次數,位於m的人出圈(數組中此處歸零),i歸零,重新報數。
y用來表示數組中對應i的位置,當y=n+1時,表示全部人循環一次,y歸零。
注意的地方:
當全部人循環一遍過後,數組中某些地方歸零,所以當y到此處時進行判斷,當a[y]=0時,y++(此處用while循環判斷,直到a[y]不等於零);
代碼:
#include<iostream>
using namespace std;
int main()
{
int n, m;
while (scanf("%d%d", &n, &m) == 2)
{
int a[1000];
for (int i = 1; i <= n; i++)
{
a[i] = i;
}
int x = 0;
int i = 1;
int y = 1;
while (x != n - 1)
{
if (i == m)
{
while (a[y] == 0)
{
y++;
if (y == n + 1)
{
y = 1;
}
}
a[y] = 0;
x++;
i = 0;
}
i++;
y++;
if (y == n + 1)
{
y = 1;
}
if (a[y] == 0)
{
while (a[y] == 0)
{
y++;
if (y == n + 1)
{
y = 1;
}
}
}
}
cout << a[y]<<endl;
}
getchar();
getchar();
}
第二種:循環鏈表
方法:
比數組要簡單,先將需要循環的數存到鏈表中,然後進行循環。
定義一個i值,每次i=m時,此節點刪除,然後直到僅剩一個結點,即爲所求值。
代碼:
#include<iostream>
using namespace std;
struct Node
{
int data;
Node *next;
};
int main()
{
int n, m;
while (scanf("%d%d", &n, &m) == 2)
{
Node *head = new Node;
head->data = 1;
Node *p = new Node;
p = head;
for (int i = 2; i <= n; i++)
{
Node *q = new Node;
q->data = i;
p->next = q;
p = q;
}
p->next = head;
int i = 1;
Node *w = new Node;
w = head;
while (head != head->next)
{
if (i+1 == m)
{
w = head->next;
head->next = w->next;
head = head->next;
i = 1;
}
else
{
head = head->next;
i++;
}
}
cout << head->data<<endl;
}
}