康拓展开-----两个排列的位置之差

#include <iostream>
#include <cstring>
#include <cstdio>
#define LL long long
using namespace std;
const int maxn=105;
const int mod=1e6+7;

int T,n,a[maxn],b[maxn];
LL fac[maxn];
int vis[maxn];

void set(int high)
{
    fac[0]=1;
    for(int i=1;i<=high;i++)
        fac[i]=(fac[i-1]*i)%mod;
}

void deal(int a[],LL &ans)
{
    ans=0;
    memset(vis,0,sizeof(vis));
    for(int i=0;i<n;i++)
    {
        int cnt=0;
        for(int j=1;j<a[i];j++) if(!vis[j]) cnt++;
        ans=(ans+((cnt*fac[n-i-1])%mod))%mod;
        vis[a[i]]=1;
    }
}
int main()
{
    set(100);
    int Case=1;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=0;i<n;i++) cin>>a[i];
        for(int i=0;i<n;i++) cin>>b[i];
        LL p1=0,p2=0,ans=0;
        deal(a,p1);deal(b,p2);

        int i=0;
        for(i=0;i<n;i++) if(a[i]!=b[i]) break;
        if(a[i]>b[i]) ans=(p1-p2)%mod;
        else ans=(p2-p1)%mod;
        cout<<"Case $"<<Case++<<":"<<endl<<(ans+mod)%mod<<endl;
    }
    return 0;
}

#include <iostream>
#include <cstring>
#include <cstdio>
#define LL long long
using namespace std;
const int maxn=105;
const int mod=1e6+7;

int T,n,a[maxn],b[maxn];
LL fac[maxn];
int vis[maxn];

void set(int high)
{
    fac[0]=1;
    for(int i=1;i<=high;i++)
        fac[i]=(fac[i-1]*i)%mod;
}

void deal(int a[],LL &ans)
{
    ans=0;
    memset(vis,0,sizeof(vis));
    for(int i=0;i<n;i++)
    {
        int cnt=0;
        for(int j=1;j<a[i];j++) if(!vis[j]) cnt++;
        ans=(ans+((cnt*fac[n-i-1])%mod))%mod;
        vis[a[i]]=1;
    }
}
int main()
{
    set(100);
    int Case=1;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=0;i<n;i++) cin>>a[i];
        for(int i=0;i<n;i++) cin>>b[i];
        LL p1=0,p2=0,ans=0;
        deal(a,p1);deal(b,p2);

        int i=0;
        for(i=0;i<n;i++) if(a[i]!=b[i]) break;
        if(a[i]>b[i]) ans=(p1-p2)%mod;
        else ans=(p2-p1)%mod;
        cout<<"Case $"<<Case++<<":"<<endl<<(ans+mod)%mod<<endl;
    }
    return 0;
}
时间: 2024-10-13 17:55:34

康拓展开-----两个排列的位置之差的相关文章

【题解】康拓展开(养生题)

[题解]康拓展开(养生题) 养生养生 编号 题目 状态 分数 总时间 内存 代码 / 答案文件 提交者 提交时间 #528662 #167. 康托展开 Accepted 100 1129 ms 8060 K C++ 11 (Clang) / 1.2 K winlere 2019-07-17 8:29:28 假如说我的排列是这样的 \[ 2 \quad3 \quad4\quad5\quad1 \] 可以从左往右扫,扫到第一个时,发现这个位置不是\(1\),而是\(2\),说明至少经历了\((2-1

康拓展开与逆康拓展开

1.康托展开的解释 康托展开就是一种特殊的哈希函数 把一个整数X展开成如下形式: X=a[n]*n!+a[n-1]*(n-1)!+...+a[2]*2!+a[1]*1! 其中,a为整数,并且0<=a<i,i=1,2,..,n {1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按从小到大排列一共6个.123 132 213 231 312 321 . 代表的数字 1 2 3 4 5 6 也就是把10进制数与一个排列对应起来. 他们间的对应关系可由康托展开来找到.

九宫重拍(bfs + 康拓展开)

问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678. 把第二个图的局面记为:123.46758 显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达.如果无论多少步都无法到达,则输出-1. 输入格式 输入第一行包含九宫的初态,第二行包含九宫的终态. 输出格式 输出最

ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)

魔板问题,一道经典的康拓展开+BFS问题,为了实现方便,我用string类来表示字符串,此前很少用string类(因为不够高效,而且相对来说我对char数组的相关函数比较熟),所以在这里也发现了很多容易被忽视的问题. 对于康拓展开不太熟系的可以先参看一篇博客:http://blog.csdn.net/zhongkeli/article/details/6966805 关于sting类,大家要注意,在赋值的时候,其赋值位置不能与首位置间存在未赋值部分. 题目需要转换思路的地方是: 我们需要将起始魔

Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 452 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

九宫重排_康拓展开_bfs

历届试题 九宫重排 时间限制:1.0s   内存限制:256.0MB 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678. 把第二个图的局面记为:123.46758 显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达.如果无论多少步都无法到达,则输出-1. 输入格

hdu 1043 Eight (八数码问题)【BFS】+【康拓展开】

<题目链接> 题目大意:给出一个3×3的矩阵(包含1-8数字和一个字母x),经过一些移动格子上的数后得到连续的1-8,最后一格是x,要求最小移动步数. 解题分析:本题用BFS来寻找路径,为了降低复杂度,用BFS从最终的目标状态开始处理,将所有搜索到状态以及对应的路径打表记录,然后对于输入的矩阵,直接查表输出答案 即可,本题还有一个难点,就是如何判断记录已经搜索过的状态,如果使用map+string(矩阵看成一维)会超时,所以我们这里用康拓展开式来记录状态. #include<cstdio

【HDOJ3567】【预处理bfs+映射+康拓展开hash】

http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 130000/65536 K (Java/Others)Total Submission(s): 4541    Accepted Submission(s): 990 Problem Description Eight-puzzle, which is also calle

java实现原数组根据下标分隔成两个子数组并且在原数组中交换两个子数组的位置

此类实现:输出一行数组数据,根据输入的下标,以下标位置为结束,将原数组分割成两组子数组.并交换两个子数组的位置,保持子数组中的元素序号不变.如:原数组为7,9,8,5,3,2 以下标3为分割点,分割为子数组一:7,9,8,5.和子数组二:3,2.经过交换算法后的结果应为:3,2,7,9,8,5 有两种交换算法<1>前插法:将子数组3,2另存在一个临时数组中,将原数组7,9,8,5,3,2每一位向后移两个位置  再将子数组3,2插入到移动好元素位置的原数组中.<2>逆置法:将原数组7