转圈游戏

题目描述:
编号从1到N的小朋友们围成了一圈。现在从1号开始报数,每个报出3的小朋友退出圈子,下一位从1开始重新报数。那么,最后剩下的那一位会是谁呢?


输入格式:
输入N的值。


输出格式:
输出留在圈里的最后一位小朋友的编号。


样例1输入:
3


样例1输出:
2


样例2输入:
100


样例2输出:
91

 

#include <iostream>
#include <list>
using namespace std;
list<int> child;
void circle(list<int>::iterator &ite)
{
    if (ite == child.end())
    {
        ite = child.begin();
    }
}
int main()
{
    int N;
    cin >> N;
    
    for (int i = 1; i <= N; i++)
    {
        child.push_back(i);
    }
    list<int>::iterator ite=child.begin(); //1
    while (1)
    {
        if (child.size() == 1)
            break;
        circle(++ite);//2
        circle(++ite);//3
        child.erase(ite++);//1
        circle(ite);
    }
    cout << *(child.begin())<<endl;


    return 0;
}

 

查看MSDN,对于erase的返回值是这样描述的:An iterator that designates the first element remaining beyond any elements removed, or a pointer to the end of the vector if no such element exists erase(ite)

意思是:

erase返回一个迭代器,指定除了删除的任何元素之外的第一个元素,或者如果不存在这样的元素则指向向量末尾的指针

 

所以对于链表这类不是顺序存储的结构,删除迭代器指向的节点  就会因为删掉当前节点后,无法遍历到往后的节点  就会造成迭代器失效,可以用以下两总方式来避免

1. child.erase(ite++);
2. ite=child.erase(ite);
posted @ 2018-08-05 22:54  uzi2008  阅读(396)  评论(0编辑  收藏  举报