链接:https://ac.nowcoder.com/acm/contest/551/H
来源:牛客网
题目描述
众所周知 CSL 不仅玩魔方很强,打麻将也很强。今天他打魔法麻将的时候,在路上撞到了一个被打乱的 n 维魔法拼图。每一块拼图的位置用一个 n 维的坐标 (p1,p2,…,pn)(p1,p2,…,pn) 来表示。将拼图的任意两块交换位置称为一步。CSL 赶着打魔法麻将时间很紧,对步数和时间也很严格,所以需要用恰好 t 步把拼图复原。请问他能做到吗?
输入描述:
第一行有一个整数 n,表示拼图的维数。 第二行有 n 个整数 d1,d2,…,dnd1,d2,…,dn,分别表示每一维的大小。
下面 2×∏ni=1di2×∏i=1ndi 行,每行有 n 个整数:第 2⋅i−12⋅i−1 行表示 第 i 块拼图的初始位置 (ai,1,ai,2,…,ai,n)(ai,1,ai,2,…,ai,n),第 2⋅i2⋅i 行表示第 i 块拼图的目标位置 (bi,1,bi,2,…,bi,n)(bi,1,bi,2,…,bi,n),保证不会有多个拼图在同一初始位置或目标位置。
最后一行有一个整数 t,表示 CSL 要求的步数。
1≤n≤101≤n≤10
n∏i=1di≤106∏i=1ndi≤106
1≤ai,j,bi,j≤dj1≤ai,j,bi,j≤dj
0≤t≤2⋅1060≤t≤2⋅106
输出描述:
如果 CSL 可以用恰好 t 步复原,在一行输出 "YES",否则输出 "NO"。
示例1
输入
1 1 1 1 1
输出
NO
示例2
输入
2 2 2 1 2 2 1 1 1 2 2 2 1 1 2 2 2 1 1 2
输出
YES
题解:这个题和前面的一个题思路是一样的https://ac.nowcoder.com/acm/contest/551/E,只不过就是哈希处理一下就可以。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define mk make_pair
const int N=2e6+10;
map<ll ,int> mp;
int n,m,t;
int a[12],id;
ll b[N],c[N];
int main()
{
ll x,y;
m=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
m*=a[i];
}
int ans=0;
for(int i=1;i<=m;i++)
{
x=0;
for(int j=1;j<=n;j++)
{
scanf("%lld",&y);
x=x*10+y;
}
b[i]=x;
mp[x]=i;
x=0;
for(int j=1;j<=n;j++)
{
scanf("%lld",&y);
x=x*10+y;
}
c[i]=x;
}
scanf("%d",&t);
int pos;
for(int i=1;i<=m;i++)
{
if(b[i]==c[i]) continue;
ans++;
pos=mp[c[i]];
// cout<<b[i]<<" "<<c[i]<<" "<<pos<<endl;
mp[b[i]]=pos;
swap(b[pos],b[i]);
}
if(ans<=t && (t-ans)%2==0) cout<<"YES\n";
else cout<<"NO\n";
return 0;
}