算法竞赛入门经典:第六章 数据结构基础 6.1卡片游戏

/*
卡片游戏:
桌上有一叠拍,从第一张牌(位于顶面的牌)开始从上往下依次编号为1~n。当至少还剩两张牌时进行以下操作:把第一张牌扔掉,然后把新的第一张放到整叠牌
的最后。输入n,输出每次扔掉的牌,以及最后剩下的牌

思路:
设置剪枝数组,凡是扔掉的牌,置剪枝标记为真,循环结束条件为还剩一张牌,有两个循环:报数循环,每次报到的删除,大循环,每次超过7进入下一次循环
关键:如何解决放在末尾的问题?用循环链表,每次放在后面。凡是放在后面,再为它开辟一个数组元素
用链表,找到末尾位置之后,从前向后遍历,如果是新1,则在末尾后加上新1,一直到只剩一个元素位置,采用尾插法
首先建立单链表n
用队列也可以做,前面弹出元素,后面末尾追加元素
*/

#include <stdio.h>
#include <stdlib.h>
#include <queue>

#define MAXSIZE 1024

using namespace std;



void cardGame(int n)
{
	queue<int> queueIntCard;
	for(int i = 1 ; i <= n;i++)
	{
		queueIntCard.push(i);
	}
	while(!queueIntCard.empty())
	{
		printf("%d ",queueIntCard.front());
		queueIntCard.pop();
		if(queueIntCard.empty())
		{
			break;
		}
		queueIntCard.push(queueIntCard.front());
		queueIntCard.pop();
		/*代码太烦,简化
		int iDel = queueIntCard.front();
		printf("%d ",iDel);
		queueIntCard.pop();
		if(queueIntCard.empty())
		{
			break;
		}
		int iMove = queueIntCard.front();
		queueIntCard.pop();
		queueIntCard.push(iMove);
		*/
	}
}


void cardGame(int n,int i)
{
	int m_queue[MAXSIZE];
	int front = 0,rear = n;//关键,模拟队列,设置队首和队尾
	for(int i = 0; i < n;i++)
	{
		m_queue[i] = i+1;
	}
	while(front < rear)
	{
		printf("%d ",m_queue[front++]);
		m_queue[rear++] = m_queue[front++];//这个经典,将队尾累加队守元素,不需要设置剪枝数组
	}
}

int main(int argc,char* argv[])
{
	int n;
	while(EOF != scanf("%d",&n))
	{
		cardGame(n,1);
	}	
	system("pause");
	return 0;
}

你可能感兴趣的:(算法竞赛)