您的位置:首页 > 其它

【noip2011】Mayan游戏

2013-10-22 23:50 309 查看
题解:

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

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

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

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

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

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

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

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

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

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

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

代码:

#include <cstdio>
#include <cstdlib>
struct info{
int a[7][9];
void print(){
for (int i=7;i>=1;i--){
for (int j=1;j<=5;j++) printf("%d ",a[j][i]);
puts("");
}
puts("");
}
}now,save[6];
int n,rem[11],srem[6][11],ans[6][3],bo[7][9];
void swap(int &a,int &b){ int x=a; a=b,b=x; }
void fall(){
for (int i=1;i<=5;i++)
for (int j=2;j<=7;j++)
if (!now.a[i][j-1] && now.a[i][j]){
int k;
for (k=j-1;!now.a[i][k] && k>=1;--k);
++k;
swap(now.a[i][j],now.a[i][k]);
}
}
void markbo(){
for (int i=1;i<=5;i++)
for (int j=1;j<=8;j++)
if (now.a[i][j]){
if (now.a[i-1][j]==now.a[i][j] && now.a[i+1][j]==now.a[i][j]){
bo[i-1][j]=1;
bo[i][j]=1;
bo[i+1][j]=1;
}
if (now.a[i][j-1]==now.a[i][j] && now.a[i][j+1]==now.a[i][j]){
bo[i][j-1]=1;
bo[i][j]=1;
bo[i][j+1]=1;
}
}
}
bool clean(){
markbo();
int res=0;
for (int i=1;i<=5;i++)
for (int j=1;now.a[i][j] && j<=8;j++)
if (bo[i][j]){
res=1;
bo[i][j]=0;
--rem[now.a[i][j]];
now.a[i][j]=0;
}
return res;
}
int work(int x,int y,int z){
swap(now.a[x][y],now.a[x+z][y]);
fall();
while (clean()) fall();
int res=0;
for (int i=1;i<=10;i++)
if (rem[i])
if (!res || res>rem[i]) res=rem[i];
return res;
}
void print(){
for (int i=1;i<=n;i++)
printf("%d %d %d\n",ans[i][0]-1,ans[i][1]-1,ans[i][2]);
exit(0);
}
void search(int t){
//printf("%d:\n",t);
//now.print();
save[t]=now;
for (int i=1;i<=10;i++) srem[t][i]=rem[i];
for (int i=1;i<=5;i++)
for (int j=1;now.a[i][j] && j<=7;j++)
for (int k=1;k>=-1;k-=2)
if (i+k>0 && i+k<=5){
if ((k==-1 && now.a[i-1][j]) || now.a[i][j]==now.a[i+k][j]) continue;
ans[t][0]=i,ans[t][1]=j,ans[t][2]=k;
int x=work(i,j,k);
if (t==n){
if (x==0) print();
}else if (x>2) search(t+1);
now=save[t];
for (int l=1;l<=10;l++) rem[l]=srem[t][l];
}
}
int main(){
scanf("%d",&n);
for (int x,i=1;i<=5;i++)
while (scanf("%d",&x),x){
now.a[i][++now.a[i][0]]=x;
++rem[x];
}
for (int i=1;i<=5;i++) now.a[i][0]=0;
search(1);
puts("-1");
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: