説明
アクアは、誕生日の贈り物として格子状のカラフルカーペットされており、より具体的には、グリッド上のカーペットの色が殺到して変更することができます。
彼女のアイドル虹猫を喜ばせるためには、アクアは~~~萌えを販売するためにカーペットの上に光のダンスを踊ることにしました
カーペットN行N列のグリッド、0~5の間の数と各グリッド、その色を表します。
アクアは、5から0の間の色を選択し、優しくステップを打つことができ、中国聯通は、グリッドは、彼女が選択したすべてのその色になり、グリッド内のカーペットの左上隅をブロックします。2つのセルの共通のエッジ、及び同じ色:ここで、通信は次のように定義されています。
アクアはキャストされているのでダンスをかわす、あまりにも多くの腹立たしいを消費しないようにするために、彼女は少なくともすべてのグリッドの色が同じになる配置するために、どのように多くの手順を知りたいと思いました。
分析
正解\(IDA * \) 、知識の台頭
\(IDDFS \)特にすぐにスローに耳を傾け、探索木の深さを制限されるが、反復深化の検索です
\(*の\)は、通常、ヒープを使用検索し、現在のステップ数を加えた評価関数であり、
まず、毎回染色前図の検索、\(1 \)は、現在の色ブロックユニコム、マーク\(2 \)現在のブロック色ユニコムの外側境界上のマーカ点を、残りの点は、標識された\(0 \)
そうであれば、評価関数は、異なる色の色の現在のユニコム残りのブロック数をとる\(0 \)、すなわち全体を図中の1つの色で染色されました。
現在のステップ数を加えた深さ、コスト関数が制限値を超えた場合は、それ\(リターン\)
ユニコムのブロック・サイズがこの汚れは意味がないことを、変更されていない場合の検索は、色の汚れを列挙します
この問題を解決することができるので、我々はまだいくつかのより多くの知識を持っているPianmen
コード
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
using namespace std;
ll fx[4]={0,0,1,-1},fy[4]={1,-1,0,0};
ll a[10][10],b[10];
ll bz[10][10];
bool flag;
ll n,ans;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void color(ll x,ll y,ll z)
{
bz[x][y]=1;
fo(i,0,3)
{
ll xx=x+fx[i],yy=y+fy[i];
if (xx<1 || xx>n || yy<1 || yy>n || bz[xx][yy]==1)continue;
bz[xx][yy]=2;
if (a[xx][yy]==z)color(xx,yy,z);
}
}
inline ll H()
{
ll tmp=0;
memset(b,0,sizeof(b));
fo(i,1,n)fo(j,1,n)if (bz[i][j]!=1 && !b[a[i][j]])b[a[i][j]]=1,++tmp;
return tmp;
}
inline bool judge(ll x)
{
ll tmp=0;
fo(i,1,n)fo(j,1,n)if (a[i][j]==x && bz[i][j]==2){++tmp,color(i,j,x);}
return tmp>0;
}
inline bool a_star(ll x)
{
ll tmp=H(),t[10][10];
if (tmp==0)return 1;
else if (tmp+x>ans)return 0;
fo(i,0,5)
{
memcpy(t,bz,sizeof(t));
if (judge(i) && a_star(x+1))return 1;
memcpy(bz,t,sizeof(bz));
}
return 0;
}
int main()
{
freopen("T1.in","r",stdin);
for (n=read();n!=0;n=read())
{
memset(bz,0,sizeof(bz)),flag=0;
fo(i,1,n)fo(j,1,n)a[i][j]=read();
color(1,1,a[1][1]);
for (ans=0;ans<=n*n;++ans)if (a_star(0))break;
printf("%lld\n",ans);
}
return 0;
}