1.問題の説明
サークルには15人がいて、1から15までの番号が付けられています。最初の人から数え始め、nに報告する人はサークルを終了します。プログラムをC言語で記述し、nの値(n> 1)を入力して、サークルに残っている最後の人の番号を出力します。
2.アルゴリズムの説明
void main()
{
リンクリストLを作成する
Lの最後に1〜15の15個の数字を1つずつ挿入します
nを入力してください
While(リンクリストLの複数の要素)
{
for(i = 1; i <n; i ++)
{
Lの最初の要素を取り、Lの最後に置きます。
Lの最初の要素を削除する
}
Lの最初の要素を出力する
Lの最初の要素を削除する
}
残りの1つであるLの最初の要素を出力します
}
三、実現する
#include<list>
#include<iostream>
using namespace std;
void print(list<int> &L)
{
if(L.size()==0)
{
cout<<"No data\n";
return;
}
list<int>::iterator it;
for(it=L.begin();it!=L.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
}
int main( )
{
list<int> L;
int i,n;
for(i=1;i<16;i++)
{
L.push_back(i);
}
//cin>>n;
n=3;
while(L.size()>1)
{
for(i=1;i<n;i++)
{
L.push_back(L.front());
L.erase(L.begin());
}
cout<<L.front()<<" ";
L.erase(L.begin());
}
cout<<endl;
cout<<"最后剩余的是:";
cout<<L.front()<<" "<<endl;
return 0;
}
第四に、効率分析
最初はm人いるとすると、これは二重サイクルです。
外層の最初のサイクルでは、尾がn-1回挿入され、頭がn回削除されます。
外側のレイヤーの2番目のループでは、尾がn-1回挿入され、頭がn回削除されます。
...
外層のm-1番目のサイクルでは、尾がn-1回挿入され、頭がn回削除されます。
要約すると、テール操作を挿入する必要性:(m-1)*(n-1)回、操作を削除する必要性:(m-1)* n回
したがって、アルゴリズムの時間の複雑さは次のとおりです。O(m * n)
提案者が意図的に物事を困難にし、nを大きくすると、毎回n回数える必要があり、円を描くようになります。
したがって、内部サイクル数nをxに最適化できます。
if(n%L.size()== 0)// nがテーブルの長さの倍数の場合、テーブルの末尾を削除する必要があります
x = L.size();
else //それ以外の場合は、残りの
x = n%L を見つけます。サイズ();
#include<list>
#include<iostream>
using namespace std;
void print(list<int> &L)
{
if(L.size()==0)
{
cout<<"No data\n";
return;
}
list<int>::iterator it;
for(it=L.begin();it!=L.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
}
int main( )
{
list<int> L;
int i,n;
for(i=1;i<16;i++)
{
L.push_back(i);
}
//cin>>n;
n=3;
while(L.size()>1)
{
int x;
if(n%L.size()==0)
x=L.size();
else
x=n%L.size();
for(i=1;i<x;i++)
{
L.push_back(L.front());
L.erase(L.begin());
}
cout<<L.front()<<" ";
L.erase(L.begin());
}
cout<<endl;
cout<<"最后剩余的是:";
cout<<L.front()<<" "<<endl;
return 0;
}
また、最適化することもできます。つまり、最初のn-1データで構成されるリンクリスト全体が削除され、リストの最後に挿入されます。
現時点では、リストテンプレートを使用しても機能せず、そのメンバー関数をすぐに使用できません。
これは、基本的な原則を学ぶ必要がある理由でもあります。