版权声明:当老鼠嘲笑猫的时候,身旁必有一个洞。 https://blog.csdn.net/qq_41138935/article/details/84665009
魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。在表演魔术前,魔术师已经将他们按照一定的顺序叠放好(有花色的一面朝下)。魔术表演过程为:一开始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;然后将其放到桌面上;第二次,魔术师数1、2;将第一张牌放到这些牌的最下面,将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;将第1、2张牌依次放到这些牌的最下面,将第三张牌翻过来正好是黑桃3;……直到将所有的牌都翻出来为止。问原来牌的顺序是如何的。
数组实现:
#include<iostream>
using namespace std;
int main(){
int a[13];
for(int i=1;i<13;i++){
a[i]=0;
}
a[0]=1;
int n=1;
for(int i=2;i<14;i++){
for(int j=0;j<i;){
if(a[n%13]==0){
j++;
if(j==i){
a[n%13]=i;
break;
}
}
n++;
}
}
for(int i=0;i<13;i++){
cout<<a[i]<<" ";
}
return 0;
}
链表实现:
#include <iostream>
using namespace std;
#define N 13
typedef struct Node
{
int data;
Node *next;
}Node,*LinkList;
void InitLinkList(LinkList &L, int n)
{
L = new Node;
L->next = L;
LinkList p;
for(int j = 0; j < n; ++j)
{
p = new Node;
p->data = 0; //初始值为零
p->next = L->next; //新节点指向原来的第一个节点
L->next = p; //头节点指向新的节点
}
}
void Magician(LinkList &L, int n)
{
LinkList p = L->next;
p->data = 1; //第一张牌是1
for(int num = 2; num <= n; ++num) //依次找到2-n牌的位置
{
int i = 0;
while(i < num)
{
p = p->next;
if(p->data == 0) ++i; //该位置有牌应该跳过
}
p->data = num;
}
}
void Print(LinkList &L)
{
LinkList p = L->next;
cout << "Print: ";
while(p != L)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
int main()
{
LinkList L;
InitLinkList(L, N);
Magician(L, N);
Print(L);
}
如果是数一张翻一张呢?
//逆着模拟,最后一张牌是13,接着12.....,f是头部标记,r是尾部标记
#include<iostream>
using namespace std;
int main(){
int a[100];
int f,r;
f=0,r=1;
a[0]=13;
for(int i=12;i>=1;i--){
a[r++]=i;
a[r++]=a[f++];
}
for(int i=r-1;i>=f;i--)
cout<<a[i]<<' ';
cout<<endl;
return 0;
}
#include<iostream>
using namespace std;
int main(){
int a[13];
int n=0;
for(int i=0;i<13;i++){
a[i]=0;
}
for(int i=1;i<=13;i++){
for(int j=0;;n++){
if(a[n%13]==0){
j++;
if(j==2){
a[n%13]=i;
break;
}
}
}
}
for(int i=0;i<13;i++){
cout<<a[i]<<" ";
}
return 0;
}