説明[タイトル]のn乗の配列は、ゲームをプレイすることを決めたある日。最初はそれぞれ(1から格子グリッド番号に格納された数に等しい
開始)。I - J | |、自分の好きな番号ジを決定するゲームプレイの各ラウンドを処理し、iとjが出会うの格子グリッドのいずれかの場合に、各グリッド=
ディは、あなたが自分のデジタルストアを交換することができます。動作シーケンスと時間制限の数。あなたは1からn個とし、各グリッドの好きな番号を知ることができます
配置。あなたはゲームが指定された状態に配置することができるかどうかを判断する必要があります。[第一列の入力形式の入力は、整数N-を含有する(1 <= N - <=
100)、グリッド・アレイの数を示します。(初期状態1-nからの)の第2行のn 1からnまでの大きさの異なる整数、指定された構成を備えます。(最終状態に達した)
第三のラインは、1からnまでのサイズのN個の整数を含む格子お気に入りの数に対応することを示しています。[]指定されたゲームへの出力フォーマットを整列させることができる場合、出力YES、そうでなければ出力
することはできません。
:タイトル鍵が質問の変換された意味で
私は、私の位置で開始番号、IはJ(POS [J] = iはポジションの最後の数 )
二つの数が他のいくつかの間接的な交換によって交換、または可能な場合には、その終了状態を達成することができます。
ABS(IJ)= NUM
(1)I> J:Ijを= NUM、J = I - NUM
(2)I <J:J - I = NUM、J = I + NUM
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<vector>
#include<string>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn = 105;
int n;
int pre[maxn];
int pos[maxn];
int fav[maxn];
void init(){
for(int i=0; i<=n; i++)
pre[i] = i;
}
int find(int x){
int r = x;
while(r!=pre[r])
r = pre[r];
while(x!=r){
int t = pre[x];
pre[x] = r;
x = t;
}
return r;
}
void join(int a,int b){
int fa = find(a);
int fb = find(b);
if(fa!=fb)
pre[fa] = fb;
}
void in_put(){
int t;
for(int i=1; i<=n; i++){
cin >> t;
pos[t] = i; //t最后要在第i的位置——要看能否与i联通起来
}
for(int i=1; i<=n; i++)
cin >> fav[i];
}
void Union(){
//位置i 喜欢的数是fav[i]
for(int i=1; i<=n; i++){
if(i+fav[i]<=n)
join(i,fav[i]+i);
if(i-fav[i]>=1)
join(i,i-fav[i]);
}
}
void check(){
bool flag = 1;
for(int i=1; i<=n; i++){
//这个位置的格子不能与最后在这个位置的格子联通
if(find(i) != find(pos[i])){
flag = 0;
break;
}
}
if(flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
int main(){
while(cin >> n){
init();
in_put();
Union();
check();
}
return 0;
}