UVA1103 古代象形符号 Ancient Messages 题解

题目链接:

https://www.luogu.org/problemnew/show/UVA1103

题目分析:

我们可以先进行矩阵的还原

for(int k=1;k<=4;k++)
{
	a[i][++cnt]=(tmp>>(4-k))&1;
}

这种使用for语句的方法在其他题解内貌似没有提及,(但其实就是把anguei的化简了一下
这样就能复原出原始的数据(01矩阵)

然后我们可以发现每一个象形文字都有可放缩性,但空白的个数是一定的。例如虫子图案就有4个空白处。

这样我们可以利用这一特性来解决问题了。

接下来用的算法是dfs乃至bfs入门都很常见的经典模型——水洼(或细胞个数)。

我们可以先判断与矩阵边缘联通的空白,全部消掉,然后剩下的空白就是文字中的了。

那么如何判断是哪个文字中的空白呢?

算法1:
刚开始,我是想先把每个文字复制一份到另一个数组里,那么在数组里经过边缘处理后剩下的空白联通块个数即为这个文字的个数。

但是后来发现没有必要。

算法2:
我们可以直接找黑点,找到一个开始扩张,扩张到的白点就是该文字的了。。。

还有就是千万不要犯一个错误:

输出的顺序是题目中图形出现的先后顺序而不是空白的个数为顺序。

endendend

代码:

//主要思路:先把二进制的01矩阵还原出来,记在a数组里,然后一一把每个象形文字单独放到b数组里,用从外向内缩0的办法找出在图形内的空白0,然后数出来,结束。 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
using namespace std;
int a[205][205];
int aa[5]={0,1,-1,0,0};
int bb[5]={0,0,0,-1,1};

int ans;
int jl[7];
int H,W;
char st[6]={'W','A','K','J','S','D'};
void pd(int xx,int yy)
{
	a[xx][yy]=2;
	for(int i=1;i<=4;i++)
	{
		int x=xx+aa[i];
		int y=yy+bb[i];
		if(x>0&&y>0&&x<=H&&y<=W&&a[x][y]==0)
		{
			a[x][y]=2;
			pd(x,y);
		}
	}
}
void search(int xx,int yy)
{
	a[xx][yy]=2;
	for(int i=1;i<=4;i++)
	{
		int x=xx+aa[i];
		int y=yy+bb[i];
		if(x>0&&y>0&&x<=H&&y<=W&&a[x][y]!=2)
		{
			
			if(a[x][y]==0)
			{
				ans++;
				pd(x,y);
			}
			else
			if(a[x][y]==1)	search(x,y);
			
		}
	}
}

int main()
{
	char s[55];
	int cntt=0;
	while(~scanf("%d%d",&H,&W)&&H!=0&&W!=0)
	{
		memset(jl,0,sizeof(jl));
		memset(a,0,sizeof(a));
		ans=0;
		cntt++;
		for(int i=1;i<=H;i++)
		{
			cin>>s;
			int cnt=0;
			for(int j=1;j<=W;j++)
			{
				int tmp;
				sscanf(s+j-1,"%1x",&tmp);
				//printf("%1x",tmp);
				//printf("\n");
				for(int k=1;k<=4;k++)
				{
					a[i][++cnt]=(tmp>>(4-k))&1;
				}
			}
		}
		W*=4;
		
		/*for(int i=1;i<=H;i++) { for(int j=1;j<=W;j++) { printf("%d",a[i][j]); } printf("\n"); }*/
		for(int k=1;k<=H;k++)
		{
			if(a[k][1]==0)pd(k,1);
			if(a[k][W]==0)pd(k,W);
		}
		for(int k=1;k<=W;k++)
		{
			if(a[1][k]==0)pd(1,k);
			if(a[H][k]==0)pd(H,k);
		}
				/* for(int qwq=1;qwq<=H;qwq++) { for(int qaq=1;qaq<=W;qaq++) { printf("%d",a[qwq][qaq]); } printf("\n"); }*/
		for(int i=1;i<=H;i++)
		{
			for(int j=1;j<=W;j++)
			{
				/*printf("--------\n"); for(int qwq=1;qwq<=H;qwq++) { for(int qaq=1;qaq<=W;qaq++) { printf("%d",a[qwq][qaq]); } printf("\n"); }*/
				if(a[i][j]==1)
				{
					//print();
					ans=0;
					search(i,j);
					//printf("ans=%d\n",ans);
					jl[ans]++;
					//printf("ans=%d\n",ans);
				}
		/* for(int i=1;i<=H;i++) { for(int j=1;j<=W;j++) { printf("%d",a[i][j]); } printf("\n"); }*/
			}
		}
		printf("Case %d: ",cntt);
		for(int j=1;j<=jl[1];j++)
			{
				printf("%c",st[1]);
			}
		for(int j=1;j<=jl[5];j++)
			{
				printf("%c",st[5]);
			}
			for(int j=1;j<=jl[3];j++)
			{
				printf("%c",st[3]);
			}
			for(int j=1;j<=jl[2];j++)
			{
				printf("%c",st[2]);
			}
			for(int j=1;j<=jl[4];j++)
			{
				printf("%c",st[4]);
			}
			for(int j=1;j<=jl[0];j++)
			{
				printf("%c",st[0]);
			}
		printf("\n");//qaqqwqwedffg
	
	}
	return 0;return 0;
}

撒花~

全部评论

相关推荐

真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务