算法竞赛入门经典(第2版)习题3-6 纵横字谜的答案 Crossword Answers UVa232

这篇博客介绍了作者在解决算法竞赛题目——UVa232(纵横字谜答案Crossword Answers)时遇到的问题。经过一上午的努力,通过调整数组大小限制从10到15,最终成功获得正确答案。

写这题用了一上午,样例数据都过了后提交发现WA。

逻辑很简单,没什么可查的,试探着把数组大小界限从10改成15发现AC了。


//#define LOCAL
//#define TESTING
#include<stdio.h>
#include<string.h>
#include<ctype.h>

char m[15][15],across[100][15],down[100][15];
int begin_x[100],begin_y[100],begin_a[100],begin_d[100];

int main()
{	
#ifdef LOCAL
freopen("xt3-6.in","r",stdin);
#endif
	int r,c,ansa,ansd,T = 1;
	bool line = false;
	while(T)
	{
		memset(m,0,sizeof(m));
		memset(begin_x,0,sizeof(begin_x));
		memset(begin_y,0,sizeof(begin_y));
		memset(begin_a,0,sizeof(begin_a));
		memset(begin_d,0,sizeof(begin_d));
		memset(across,0,sizeof(across));		
		memset(down,0,sizeof(down));	
		ansa=0;
		ansd=0;	

		//读取网格行列数 
		scanf("%d", &r);		 
		if(r==0) return 0;
		scanf("%d", &c);
		getchar();
		//读取网格行列数结束 
		
		// 读取网格 
		char temp;
		temp = getchar();
		//printf("temp= %c\n", temp);
		if(isalpha(temp)||temp == '*')
		{
			for(int i = 0; i  < r; i++)
			{
				for(int j = 0; j < c; j++)
				{
					if(i+j == 0) m[0][0] = temp;
					else m[i][j] = getchar();					
					if(!isalpha(m[i][j])&&m[i][j]!='*') j--;
					//printf("%c", m[i][j]);
				}
				
			}
		}
		else temp = getchar();
		//读取网格结束
		
		//确定起始格 		
		int begin = 0;
		
		for(int i = 0; i < r; i++)
		{
			for(int j = 0; j < c; j++)
			{
				if(m[i][j]!='*')
				{
					if((i-1<0)||(j-1<0))
					{
					begin_x[begin] = i;
					begin_y[begin] = j;
					begin++;
					}
					else if(m[i-1][j]=='*' || m[i][j-1]=='*')
					{
					begin_x[begin] = i;
					begin_y[begin] = j;
					begin++;
					}
					
				}
				
			}
		}
		//确定起始格结束 
		
		//找出横向单词 		
		for(int i = 0; i < begin; i++)
		{
			int x, y;
			x = begin_x[i];
			y = begin_y[i];			
			if(y-1<0||m[x][y-1]=='*')
			{
				begin_a[ansa]=i+1;				
				for(int j = 0; j+y<c; j++)
				{
					if(m[x][y+j]!='*') 
					{
						across[ansa][j] = m[x][y+j];
						//printf("ansa=%d j=%d y=%d across=%s\n", ansa, j, y, across[ansa]);
					}
					else break;
				}
				ansa++;
			}
		
		}		
		//找出横向单词结束 
		
		//找出竖向单词 
		for(int i = 0; i < begin; i++)
		{
			int x, y;
			x = begin_x[i];
			y = begin_y[i];			
			if(x-1<0||m[x-1][y]=='*')
			{
				begin_d[ansd]=i+1;				
				for(int j = 0; j+x<r; j++)
				{
					if(m[x+j][y]!='*') 
					{
						down[ansd][j] = m[x+j][y];
						//printf("ansa=%d j=%d y=%d across=%s\n", ansa, j, y, across[ansa]);
					}
					else break;
				}
				ansd++;
			}
		
		}		
		//找出竖向单词结束 
		
		//输出结果
		if(line) printf("\n");
		line = true;
		printf("puzzle #%d:\n",T);
#ifdef TESTING		
		printf("r=%d c=%d begin=%d\n",  r, c,begin);
		for(int i = 0; i  < r; i++)
		{
			for(int j = 0; j < c; j++)
			{
				printf("%c", m[i][j]);
				if(j == c-1) printf("\n");
			}
				
		}			
#endif	
		printf("Across\n");
		for(int i = 0; i < ansa; i++) printf("%3d.%s\n",begin_a[i], across[i]);
		printf("Down\n");
		for(int i = 0; i < ansd; i++) printf("%3d.%s\n",begin_d[i], down[i]);
			
		//输出结果结束
		T++;
	}
	return 0; 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值