poj 1721 CARDS 洗牌机

本文介绍了一个基于卡片的游戏问题及其解决方案,该问题涉及置换群的快速幂运算。通过分析游戏规则,文章提出了一种高效算法来逆向求解经过多次双倍洗牌后的初始卡片排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CARDS
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 1684 Accepted: 877

Description

Alice and Bob have a set of N cards labelled with numbers 1 ... N (so that no two cards have the same label) and a shuffle machine. We assume that N is an odd integer. 
The shuffle machine accepts the set of cards arranged in an arbitrary order and performs the following operation of double shuffle : for all positions i, 1 <= i <= N, if the card at the position i is j and the card at the position j is k, then after the completion of the operation of double shuffle, position i will hold the card k. 

Alice and Bob play a game. Alice first writes down all the numbers from 1 to N in some random order: a1, a2, ..., aN. Then she arranges the cards so that the position ai holds the card numbered a i+1, for every 1 <= i <= N-1, while the position aN holds the card numbered a1. 

This way, cards are put in some order x1, x2, ..., xN, where xi is the card at the i th position. 

Now she sequentially performs S double shuffles using the shuffle machine described above. After that, the cards are arranged in some final order p1, p2, ..., pN which Alice reveals to Bob, together with the number S. Bob's task is to guess the order x1, x2, ..., xN in which Alice originally put the cards just before giving them to the shuffle machine. 

Input

The first line of the input contains two integers separated by a single blank character : the odd integer N, 1 <= N <= 1000, the number of cards, and the integer S, 1 <= S <= 1000, the number of double shuffle operations. 
The following N lines describe the final order of cards after all the double shuffles have been performed such that for each i, 1 <= i <= N, the (i+1) st line of the input file contains pi (the card at the position i after all double shuffles). 

Output

The output should contain N lines which describe the order of cards just before they were given to the shuffle machine. 
For each i, 1 <= i <= N, the ith line of the output file should contain xi (the card at the position i before the double shuffles). 

Sample Input

7 4
6
3
1
2
4
7
5

Sample Output

4
7
5
6
1
2
3

Source

CEOI 1998



翻译在

算法合集之《置换群快速幂运算 研究与探讨》

中有


要注意这个题目的每一次操作都不是一次置换,要按照它规定的方式操作。

反复操作找出周期circle,题目告诉了你终点状态ed,和操作了s次,要你求起始状态st。
首先s=s%circle。
相当于变换了这么多次。
然后从终点 再变换 circle-s 次,即可得到起点。
很像链表中的一个操作。


#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)
#define  lson   num<<1,le,mid
#define rson    num<<1|1,mid+1,ri
#define MID   int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk    make_pair
#define _f     first
#define _s     second
using namespace std;
//const int INF=    ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn= 1000+20    ;
//const int maxm=    ;
//by yskysker123
int n,s,circle;
int A[maxn],B[maxn],C[maxn];
void GetCircle()
{
    circle=0;
    while(1)
    {
        circle++;
        for(int i=1;i<=n;i++)
          B[i]=  C[C[i]];

        int i;
        for(i=1;i<=n;i++)
            if(B[i]!=A[i])  break;

        if(i>n)  break;
        for(int i=1;i<=n;i++)  C[i]=B[i];
    }


}


void Work(int k)
{
    for(int i=1;i<=k;i++)
    {
        for(int j=1;j<=n;j++)  B[j]=A[A[j]];
        for(int j=1;j<=n;j++)  A[j]=B[j];
    }
    for(int i=1;i<=n;i++)
        printf("%d\n",B[i]);
}
int main()
{
   while(~scanf("%d%d",&n,&s))
   {
       for(int i=1;i<=n;i++)  scanf("%d",&A[i]),B[i]=C[i]=A[i];
       GetCircle();
       s=s%circle;
       int k=circle-s;
       Work(k);


   }

    return 0;
}



### 扑克牌排序算法 扑克牌排序可以通过多种方法实现,其中一种常见的思路是利用字典映射来表示扑克牌的大小顺序,并基于此进行自定义排序。以下是具体的解决方案: #### 解决方案描述 为了实现扑克牌排序,可以按照以下逻辑编写代码: 1. 定义一张扑克牌的花色和数值对应的优先级表。 2. 将输入的扑克牌转换为可比较的形式(例如元组),并依据优先级表进行排序。 3. 输出排序后的结果。 下面是一个完整的 Python 实现示例: ```python def poker_sort(cards): # 定义花色和数值的优先级 suit_order = {'♠': 4, '♥': 3, '♦': 2, '♣': 1} # 黑桃 > 红心 > 方片 > 梅花 value_order = { 'A': 14, 'K': 13, 'Q': 12, 'J': 11, 'T': 10, '9': 9, '8': 8, '7': 7, '6': 6, '5': 5, '4': 4, '3': 3, '2': 2 } # 自定义排序键 def sort_key(card): value, suit = card[:-1], card[-1] return (suit_order[suit], value_order[value]) # 对扑克牌列表进行排序 sorted_cards = sorted(cards, key=sort_key, reverse=True) return sorted_cards # 测试用例 cards = ['2♠', 'A♣', 'K♥', 'Q♦', 'J♣'] sorted_result = poker_sort(cards) print(sorted_result) ``` 上述代码实现了扑克牌的降序排列,黑桃最高,梅花最低;同花色情况下,`A` 的权重最大,`2` 最小[^1]。 --- #### 关于离散化与排序的关系 在某些场景下,扑克牌排序也可以看作是一种 **数据有序化** 或者 **离散化** 的过程。通过将复杂的扑克牌信息转化为简单的整数序列来进行高效操作,这正是引用中提到的数据结构优化思想的一部分[^2]。 --- #### 输入输出示例 假设输入如下一组扑克牌: ```plaintext ['2♠', 'A♣', 'K♥', 'Q♦', 'J♣'] ``` 运行以上代码后,输出的结果将是: ```plaintext ['A♣', 'K♥', 'Q♦', 'J♣', '2♠'] ``` --- #### 性能分析 该算法的时间复杂度主要由 `sorted()` 函数决定,其时间复杂度为 \(O(n \log n)\),适用于大多数实际应用场景。对于大规模数据集,还可以考虑进一步优化排序策略或者采用其他高级数据结构[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值