魔术师发牌问题C++
问题:魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。在表演魔术前,魔术师已经将他们按照一定的顺序叠放好(有花色的一面朝下)。魔术表演过程为:一开始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;然后将其放到桌面上;第二次,魔术师数1、2;将第一张牌放到这些牌的最下面,将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;将第1、2张牌依次放到这些牌的最下面,将第三张牌翻过来正好是黑桃3;……直到将所有的牌都翻出来为止。问原来牌的顺序是如何的。
思路:需要先创建一个循环链表,包含13个元素,每个元素初始值设置为0;然后用当魔术师手中持牌的点数依次填充循环链表,改变其初始值;最后遍历循环链表,输出魔术师手中持牌的顺序。
#include <iostream>
using namespace std;
#define N 13
class Node{
public:
Node *next;
int data;
};
class CircleList{
private:
Node *first;
int length;
public:
//定义如何创建一个循环链表,注意返回头节点
Node *creatList(int n){
first=new Node;
Node *s,*r;
r=first;
for(int i=0;i<n;i++){
s=new Node;
s->data=0;
r->next=s;
r=s;
}
r->next=first;
return first;
}
//清除链表
void clearList(){
Node *p=first;
while(p->next!=first){
Node *temp=p->next;
delete p;
p=temp;
}
}
//遍历。注意由于头节点没有赋值,是系统随机赋值的,
//并不是我们想要的结果,所以遍历时会将first节点跳过。
//若first节点单独赋值,并希望打印出来,则P节点和循环结束条件有所不同
void traverse(){
Node *p=first->next;
while (p!=first){
cout<<p->data<<"\t";
p=p->next;
}
}
};
//魔术师的牌排列顺序实现。传入一个循环链表的头节点,给循环链表的节点重新赋值,得到牌的顺序
void magic(Node *pokerHead){
//对于头节点要不要使用,是否要单独赋值的细节处理不同
//则遍历的细节也不同
//Node *poker=pokerHead;//使用头节点的方式
Node *poker=pokerHead->next; //不使用头节点的方式
poker->data=1;
int countNum=2;
while(1){
for(int i=0;i<countNum;i++){
poker=poker->next;
if(poker->data!=0){
i--;
}
}
if(poker->data==0){
poker->data=countNum;
countNum++;
if(countNum>N) break;
}
}
}
void display(Node *pokerHead){
/*
//使用头节点的遍历方式
Node *p=pokerHead;
while(p->next!=pokerHead){
cout<<p->data<<"\t";
p=p->next;
}
cout<<p->data;
*/
//不使用头节点的遍历方式
Node *p=pokerHead->next;
while(p!=pokerHead){
cout<<p->data<<"\t";
p=p->next;
}
}
int main(){
CircleList circle1;
Node *p=circle1.creatList(N);
circle1.traverse();
cout<<"-----"<<endl;
magic(p);
display(p);
return 0;
}
页:
[1]