【noip2011】Mayan游戏

题解:

刷了一天的noip啊 做了10题! 突然找回了做马拉松的感觉- -

我中午竟然放弃治疗去看视频 做到晚上累得都快挂了 用电脑放一些rock 把音乐当咖啡硬撑下来 但是还是没能刷3届

唉 显然速度刷题是很容易忘的 简单写一些题解 然后睡觉去(- -。zZ)

 

赤裸裸的搜索 但是要加一些剪枝

1.如果交换的两个方块颜色相同则不换

2.如果移动时是向左且左边有方块则不动(左边的往右效果一样)

3.如果任意颜色发方块个数为1或2 显然无解return

我只加了这些剪枝速度貌似还不错 vijos上1300ms左右

关键是很多人说这题很复杂 - -?

其实思路清楚就不会(表示半小时搞定) 我感觉做这题就像在做游戏一样

可以写两个函数fall 和clean做掉落和清除 然后在要调用的地方写函数就会觉得清晰多了

 

代码:

 1 #include <cstdio>

 2 #include <cstdlib>

 3 struct info{

 4     int a[7][9];

 5     void print(){

 6         for (int i=7;i>=1;i--){

 7             for (int j=1;j<=5;j++) printf("%d ",a[j][i]);

 8             puts("");

 9         }

10         puts("");

11     }

12 }now,save[6];

13 int n,rem[11],srem[6][11],ans[6][3],bo[7][9];

14 void swap(int &a,int &b){ int x=a; a=b,b=x; }

15 void fall(){

16     for (int i=1;i<=5;i++)

17     for (int j=2;j<=7;j++)

18     if (!now.a[i][j-1] && now.a[i][j]){

19         int k;

20         for (k=j-1;!now.a[i][k] && k>=1;--k);

21         ++k;

22         swap(now.a[i][j],now.a[i][k]);

23     }

24 }

25 void markbo(){

26     for (int i=1;i<=5;i++)

27     for (int j=1;j<=8;j++)

28     if (now.a[i][j]){

29         if (now.a[i-1][j]==now.a[i][j] && now.a[i+1][j]==now.a[i][j]){

30             bo[i-1][j]=1;

31             bo[i][j]=1;

32             bo[i+1][j]=1;

33         }

34         if (now.a[i][j-1]==now.a[i][j] && now.a[i][j+1]==now.a[i][j]){

35             bo[i][j-1]=1;

36             bo[i][j]=1;

37             bo[i][j+1]=1;

38         }

39     }

40 }

41 bool clean(){

42     markbo();

43     int res=0;

44     for (int i=1;i<=5;i++)

45     for (int j=1;now.a[i][j] && j<=8;j++)

46     if (bo[i][j]){

47         res=1;

48         bo[i][j]=0;

49         --rem[now.a[i][j]];

50         now.a[i][j]=0;

51     }

52     return res;

53 }

54 int work(int x,int y,int z){

55     swap(now.a[x][y],now.a[x+z][y]);

56     fall();

57     while (clean()) fall();

58     int res=0;

59     for (int i=1;i<=10;i++)

60     if (rem[i])

61     if (!res || res>rem[i]) res=rem[i];

62     return res;

63 }

64 void print(){

65     for (int i=1;i<=n;i++)

66     printf("%d %d %d\n",ans[i][0]-1,ans[i][1]-1,ans[i][2]);

67     exit(0);

68 }

69 void search(int t){

70     //printf("%d:\n",t);

71     //now.print();

72     save[t]=now;

73     for (int i=1;i<=10;i++) srem[t][i]=rem[i];

74     for (int i=1;i<=5;i++)

75     for (int j=1;now.a[i][j] && j<=7;j++)

76     for (int k=1;k>=-1;k-=2)

77     if (i+k>0 && i+k<=5){

78         if ((k==-1 && now.a[i-1][j]) || now.a[i][j]==now.a[i+k][j]) continue;

79         ans[t][0]=i,ans[t][1]=j,ans[t][2]=k;

80         int x=work(i,j,k);

81         if (t==n){

82             if (x==0) print();

83         }else if (x>2) search(t+1);

84         now=save[t];

85         for (int l=1;l<=10;l++) rem[l]=srem[t][l];

86     }

87 }

88 int main(){

89     scanf("%d",&n);

90     for (int x,i=1;i<=5;i++)

91     while (scanf("%d",&x),x){

92         now.a[i][++now.a[i][0]]=x;

93         ++rem[x];

94     }

95     for (int i=1;i<=5;i++) now.a[i][0]=0;

96     search(1);

97     puts("-1");

98 }
View Code

 

你可能感兴趣的:(Maya)