魔术师发牌问题---来自算法之美

版权声明:当老鼠嘲笑猫的时候,身旁必有一个洞。 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;
}

猜你喜欢

转载自blog.csdn.net/qq_41138935/article/details/84665009