题目传送门: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
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"。
解题思路:
类似于前面的那道一维的交换题目 CSL的魔法
不过这里是多维的,怎样形成映射呢?
用 string !
AC code:
1 #include <bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 #define LL long long 4 #define inc(i, j, k) for(int i = j; i <= k; i++) 5 #define rep(i, j, k) for(int i = j; i < k; i++) 6 #define mem(i, j) memset(i, j, sizeof(i)) 7 #define gcd(i, j) __gcd(i, j) 8 #define pb push_back 9 using namespace std; 10 const int MAXN = 2e5+10; 11 12 string st[MAXN], ed[MAXN], str; 13 map<string, int>vis; 14 int N, t; 15 int main() 16 { 17 int num; 18 scanf("%d", &N); 19 int len = 1; 20 inc(i, 1, N){ 21 scanf("%d", &num); 22 len*=num; 23 } 24 // printf("len %d\n", len); 25 26 getchar(); 27 // /* 28 inc(i, 1, len){ 29 getline(cin, str); 30 st[i] = str; 31 vis[str] = i; 32 getline(cin, str); 33 ed[i] = str; 34 } 35 scanf("%d", &t); 36 LL ans = 0; 37 inc(i, 1, len){ 38 if(st[i] != ed[i]){ 39 ans++; 40 int tp = vis[ed[i]]; 41 swap(st[i], st[tp]); 42 vis[st[i]] = i; 43 vis[st[tp]] = tp; 44 } 45 if(ans > t) break; 46 } 47 if(ans > t) puts("NO"); 48 else if((t-ans)%2 == 0) puts("YES"); 49 else puts("NO"); 50 // */ 51 return 0; 52 }