Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pipes, which is marked from A to K, as Figure 1 shows.
2 2 DK HF 3 3 ADC FJK IHE -1 -1Sample Output
2
3
题目:题意就是有A到K11种田,任意输入两个数字,范围为1到50,求组成的水田最多需要多少个水泵?
传统思路:这题传统思路就是,先将组成的图表示出来,判断每个小图片四周的节点,如果可以连,就从下一个图片一直暴力下去,直到走不下去为止。然后将走过的所有路标记一下,在遍历组成的图,重复上诉步骤,直到所有位置都被标记。这种方法使能够解出来的,题目要求的范围比较小,开的时间为1s,完全可以暴力。这里,我们讲另一种思路。
二进制求解:用个数组将所有图片分别用一个数来表示,这里采用的是二进制的形式,下为起始位置,逆时针旋转,有端点为1,无端点为0。其思路是,以每个字符为起点,向上下左右进行查找,直到找到重复的点或越界为止。这里有一点必须注意,那就是首先我们需要把所有字符串都存起来,不能边存边查。这样做的目的很明显,就是为了减少运行数据,避免重复,达到优化的目的。我们查找的时候是运用了贪心的思想,把附近能达到的都走一遍,然后都标记,后面就不需要再查找了。而且,如果把后面的标记判断那一步(if(ans[i][j]) continue) 删了,就会出错,原因是一旦删了,后面已经被标记的还会重复计算,ans还是会多加重复的次数,所以那一步是必须的。//这是图像转化为数字
话不多说,代码如下:
#include
#include
#include
#include
#include
using namespace std;
char s[55][55];
int vis[55][55],xx[]= {0,0,1,-1},yy[]= {1,-1,0,0},tp[]= {3,6,9,12,10,5,7,11,13,14,15}; //利用二进制,从最下面开始,有端点表示为1,无端点表示为0
int flag,n,m,ans;
int check(int x,int y,int tx,int ty,int cn)
{
flag=0;
if(tx<1||tx>n||ty<1||ty>m)//判断是否越界
return false;
int ta,tb;
ta=s[x][y]-'A';
tb=s[tx][ty]-'A';
if(cn==0)//向右查找
{
if(((tp[ta]>>2)&1)&&(tp[tb]&1))
flag=true;
}
else if(cn==1)//向左查找
{
if(((tp[tb]>>2)&1)&&(tp[ta]&1))
flag=true;
}
else if(cn==2)//向上查找
{
if(((tp[ta]>>3)&1)&&((tp[tb]>>1)&1))
flag=true;
}
else//向下查找
if(((tp[tb]>>3)&1)&&((tp[ta]>>1)&1))
flag=true;
return flag;
}
void dfs(int x,int y)
{
if(vis[x][y])//从当前位置向四处查找,直到找到某个位置是走过的位置为止
return;
vis[x][y]=1;//把所有走过的地方都标记一次
for(int i=0; i<4; i++) //上下左右都进行查找
{
int tx=x+xx[i];
int ty=y+yy[i];
if(check(x,y,tx,ty,i))
dfs(tx,ty);
}printf("%d\n",ans);
}
int main()
{
int i,j;
while(~scanf("%d %d",&n,&m)&&(n+1)&&(m+1))
{
ans=0;
memset(vis,0,sizeof(vis));
for(i=1; i<=n; i++)
scanf("%s",s[i]+1);//下标从1开始
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
{
if(vis[i][j])//如果已经走过,就不必再走了,而不是相同的元素不能重复
continue;
ans++;
dfs(i,j);
}
}
printf("%d\n",ans);
}
return 0;
大家还有任何疑问欢迎留言,大家一起进步!