1. 程式人生 > >Educational Codeforces Round 52D(array,模擬最短路)

Educational Codeforces Round 52D(array,模擬最短路)

soft amp round 最短 size its change urn ++

#include<bits/stdc++.h>
using namespace std;
int n,x;
int chess[17*17];//記錄棋盤上的number
array<int,2>pace[17*17*3][17*17*3],dp[17*17][3];//first記錄root,second記錄change
array<int,2>operator+(const array<int,2>a,const array<int,2> b){
return {a[0]+b[0],a[1]+b[1]};
}
int main(){
memset(pace,1,sizeof(pace));//最大為1


memset(dp,1,sizeof(dp));//最大為1
scanf("%d",&n);
for(int i=0;i<n*n;i++){
scanf("%d",&x);
x--;
chess[x]=i;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<3;k++){
for(int l=0;l<3;l++){
pace[(i*n+j)*3+k][(i*n+j)*3+l]={1,1};//i*n後+j可以表示棋盤上n*n的所有位置,*3後可以用一維表示位置和用哪一種棋子走到這裏的,不*3多開一維也可以

}
}
for(int k=0;k<n;k++){
for(int l=0;l<n;l++){
if(i==k||j==l)//車一步可以走到
pace[(i*n+j)*3][(k*n+l)*3]={1,0};
else if(abs(i-k)+abs(j-l)==3)//騎士一步可以走到
pace[(i*n+j)*3+2][(k*n+l)*3+2]={1,0};//+1用來區分是誰走的

if(i+j==k+l||i-j==k-l)//皇後一步可以走到
pace[(i*n+j)*3+1][(k*n+l)*3+1]={1,0};//+2用於區分
}
}
}
}
for(int k=0;k<n*n*3;k++){
for(int i=0;i<n*n*3;i++){
for(int j=0;j<n*n*3;j++){
pace[i][j]=min(pace[i][k]+pace[k][j],pace[i][j]);//最短路
}
}
}
dp[0][0]=dp[0][1]=dp[0][2]={};
for(int i=1;i<n*n;i++){
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
dp[i][j]=min(dp[i-1][k]+pace[chess[i-1]*3+k][chess[i]*3+j],dp[i][j]);
}
}
}
array<int,2>a=min({dp[n*n-1][0],dp[n*n-1][1],dp[n*n-1][2]});//分別為初始的三種棋子,首先比較第一個元素選取最小,依次比較後續元素選取最小
printf("%d %d",a[0],a[1]);
return 0;
}

Educational Codeforces Round 52D(array,模擬最短路)