【IDA*】codevs 2495:水叮當的舞步


2495 水叮當的舞步

  

題目描述 Description

  水叮當得到了一塊五顏六色的格子形地毯作為生日禮物,更加特別的是,地毯上格子的顏色還能隨着踩踏而改變。
  為了討好她的偶像虹貓,水叮當決定在地毯上跳一支輕盈的舞來賣萌~~~

  地毯上的格子有N行N列,每個格子用一個0~5之間的數字代表它的顏色。
  水叮當可以隨意選擇一個0~5之間的顏色,然后輕輕地跳動一步,左上角的格子所在的聯通塊里的所有格子就會變成她選擇的那種顏色。這里連通定義為:兩個格子有公共邊,並且顏色相同。
  由於水叮當是施展輕功來跳舞的,為了不消耗過多的真氣,她想知道最少要多少步才能把所有格子的顏色變成一樣的。

輸入描述 Input Description

  每個測試點包含多組數據。
  每組數據的第一行是一個整數N,表示地攤上的格子有N行N列。
  接下來一個N*N的矩陣,矩陣中的每個數都在0~5之間,描述了每個格子的顏色。
  N=0代表輸入的結束。

輸出描述 Output Description

  對於每組數據,輸出一個整數,表示最少步數。

樣例輸入 Sample Input

  2
  0 0 
  0 0
  3 
  0 1 2 
  1 1 2
  2 2 1
  0

樣例輸出 Sample Output

  0
  3

數據范圍及提示 Data Size & Hint

  對於30%的數據,N<=5
  對於50%的數據,N<=6
  對於70%的數據,N<=7
  對於100%的數據,N<=8,每個測試點不多於20組數據。

第二組樣例解釋:
  0 1 2       1 1 2       2 2 2      1 1 1
  1 1 2 --> 1 1 2 --> 2 2 2 --> 1 1 1
  2 2 1       2 2 1       2 2 1      1 1 1


 

   一開始打了一個四不像的搜索。。只有30..

  后來瞄了一眼題解。。

  發現解題思路還是很神的

  估價函數比較裸:當前剩余顏色數目

  剩下就是怎么搜索了

  把圖分為3種顏色

  與(1,1)在一個同色聯通塊里為1 

  在聯通塊邊界但是不與聯通塊同色為2

  剩下為0

  每次變顏色搜遍整個圖然后把與要變顏色相同的且顏色為2的格子拓展一下

  最后都是1的時候退出

  IDA*

  

  1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<algorithm>
5
6 using namespace std;
7
8 int n=99,map[11][11],X[4]={0,0,1,-1},Y[4]={1,-1,0,0},MAP[11][11];
9
10 bool g[11][11];
11
12 void pre(int x,int y,int col)
13 {
14 MAP[x][y]=1;
15 if(x==1&&y==1)col=map[1][1];
16 for(int i=0;i<4;i++)
17 {
18 int xx=x+X[i],yy=y+Y[i];
19 if(xx<=n&&yy<=n&&xx>=1&&yy>=1&&MAP[xx][yy]!=1)
20 {
21 if(map[xx][yy]==col)pre(xx,yy,col);
22 else MAP[xx][yy]=2;
23 }
24 }
25 }
26
27 /*void ran(int x,int y,int col)
28 {
29 for(int i=0;i<4;i++)
30 {
31 int xx=x+X[i],yy=y+Y[i];
32 if(xx<=n&&yy<=n&&xx>=1&&yy>=1&&map[xx][yy]==map[1][1]&&(!(xx+yy==2&&xx==1)))
33 map[xx][yy]=col,ran(xx,yy,col);
34 }
35 }*/
36
37 int get()
38 {
39 int res[6]={0},nu=1;
40 for(int i=1;i<=n;i++)
41 for(int j=1;j<=n;j++)
42 if(!res[map[i][j]] && MAP[i][j]!=1)
43 {
44 res[map[i][j]]=1;
45 nu++;
46 }
47 return nu;
48 }
49
50 void dfs(int x,int y,int col)
51 {
52 MAP[x][y]=1;
53 for(int i=0;i<4;i++)
54 {
55 int xx=X[i]+x,yy=y+Y[i];
56 if(xx<=n&&yy<=n&&xx>=1&&yy>=1&&MAP[xx][yy]!=1)
57 {
58 if(map[xx][yy]==col)dfs(xx,yy,col);
59 else MAP[xx][yy]=2;
60 }
61 }
62 }
63
64 bool fill(int col)
65 {
66 int ret=0;
67 for(int i=1;i<=n;i++)
68 for(int j=1;j<=n;j++)
69 if(MAP[i][j]==2&&map[i][j]==col)
70 {
71 ret++;
72 dfs(i,j,col);
73 }
74 return ret;
75 }
76
77 bool IDA(int k)
78 {
79 /*memset(g,0,sizeof(g));
80 int stop=find(1,1,0),ctrl=0,temp[11][11];
81 if(!stop)return 1;
82 else if(!k)return 0;
83 for(int i=0;i<=5;i++)
84 if(i!=map[1][1]&&(stop&(1<<i))!=0)
85 {
86 memcpy(temp,map,sizeof(map));
87 ran(1,1,i);
88 map[1][1]=i;
89 ctrl=IDA(k-1);
90 if(!ctrl)memcpy(map,temp,sizeof(temp));
91 else return 1;
92 }
93 return 0;*/
94 int nu=get();
95 if(nu==1)return 1;
96 else if(k+1<nu)return 0;
97 int temp[11][11]={0};
98 for(int i=0;i<=5;i++)
99 {
100 memcpy(temp,MAP,sizeof(MAP));
101 if(fill(i) && IDA(k-1))return 1;
102 memcpy(MAP,temp,sizeof(temp));
103 }
104 return 0;
105 }
106
107 int main()
108 {
109 while(1)
110 {
111 scanf("%d",&n);
112 if(!n)break;
113 for(int i=1;i<=n;i++)
114 for(int j=1;j<=n;j++)
115 scanf("%d",&map[i][j]);
116 memset(MAP,0,sizeof(MAP));
117 pre(1,1,map[1][1]);
118 for(int i=0;i<=n*n;i++)
119 if(IDA(i)){printf("%d\n",i);break;}
120 }
121 return 0;
122 }
View Code

  

 

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com