题目描述:
一个五子连珠的游戏。给定一个10乘10的棋盘和10种颜色的棋子分布图。移动其中任意一个棋子任意步数,求这样做一次动作最多能得到多少分。
解题思路:
回溯。要注意一些细节问题,诸如计算得分时注意多组交叉加分的情况。另外就是输出格式……
代码:
#include <stdio.h>
#include <stdlib.h>
#define N 11
int G[N][N],max=0,flag[N][N];
int judge(int i, int j)
{
int sum=0,f=0;
int pos_x=i,pos_y = j;
int up,down,left,right,lux,ldx,rux,rdx;
//找纵向
i = pos_x;
while(i>0 && G[i-1][pos_y]==G[pos_x][pos_y])
i--;
up = i;
i = pos_x;
while(i<9 && G[i+1][pos_y] == G[pos_x][pos_y])
i++;
down = i;
if(down - up >= 4)
{
sum+=down - up+1;
f=1;
}
//找横向
j=pos_y;
while(j>0 && G[pos_x][j-1] == G[pos_x][pos_y])
j--;
left = j;
j=pos_y;
while(j<9 && G[pos_x][j+1] == G[pos_x][pos_y])
j++;
right = j;
if(right-left >= 4)
{
sum+=right-left+1-f;
f=1;
}
//找左斜向
i=pos_x;
j=pos_y;
while(i>0&&j>0&&G[i-1][j-1]==G[pos_x][pos_y])
{
i--;
j--;
}
lux = i;
i=pos_x;
j=pos_y;
while(i<9&&j<9 && G[i+1][j+1]==G[pos_x][pos_y])
{
i++;
j++;
}
ldx = i;
//printf("左斜向,找到lux=%d,ldx=%d.\n",lux,ldx);
if(ldx-lux >= 4)
{
sum+= ldx-lux+1-f;
f=1;
}
//找右斜向
i=pos_x;
j=pos_y;
while(i>0&&j<9&&G[i-1][j+1]==G[pos_x][pos_y])
{
i--;
j++;
}
rux = i;
i=pos_x;
j=pos_y;
while(i<9&&j>0 && G[i+1][j-1]==G[pos_x][pos_y])
{
i++;
j--;
}
rdx = i;
if(rdx-rux >= 4)
sum+= rdx-rux+1-f;
return sum;
}
void move(int i, int j, int data)
{
int t;
if(i<0 || j<0 || i>9 || j>9 || G[i][j]!=-1 || flag[i][j] != 0)
;
else
{
flag[i][j] = 1;
G[i][j] = data;
//判断处在这个位置上的加分
t = judge(i,j);
G[i][j] = -1;
if(t != 0)
{
if(t>max)
max = t;
}
else
{
move(i-1,j,data);
move(i+1,j,data);
move(i,j-1,data);
move(i,j+1,data);
}
}
}
main()
{
char str[N];
int i,j,f,tmp;
int cc=1;
while(scanf("%s",&str)!=EOF)
{
for(j=0;j<10;j++)
if(str[j]=='.')
G[0][j] = -1;
else
G[0][j] = str[j]-'0';
for(i=1;i<=9;i++)
{
scanf("%s",&str);
for(j=0;j<10;j++)
if(str[j]=='.')
G[i][j] = -1;
else
G[i][j] = str[j]-'0';
}
f=1;
for(i=0;i<=9;i++)
for(j=0;j<=9;j++)
if(G[i][j]!=-1)
{
if(judge(i,j)!=0)
f=0;
}
if(1 == f) //如果所有石子都不能加分
{
max = 0;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
if(G[i][j]!=-1)
{
memset(flag,0,sizeof(flag));
tmp = G[i][j];
G[i][j] = -1;
// printf("move %d %d.\n",i,j);
move(i,j,tmp);
G[i][j] = tmp;
}
if(cc!=1)
printf("\n");
printf("Case #%d: %d\n",cc,max);
}
else
{
if(cc!=1)
printf("\n");
printf("Case #%d: Waiting!\n",cc);
}
cc++;
}
// system("pause");
return 0;
}