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:
我们可以直接找黑点,找到一个开始扩张,扩张到的白点就是该文字的了。。。

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

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

e n d end end

代码:

//主要思路:先把二进制的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;
}

撒花~

全部评论

相关推荐

02-12 20:22
重庆大学 Java
字节暑期刚入职四天,因为是年前,所以很多正职都放假走了,也就没有给我分配mt,然后有一个老哥在我来的时候给我发了一个landing手册,然后还有关于部门业务的白皮书,还有一些业务代码。然后本人是java面的,进来第一次接触go语言&nbsp;前面几天熟悉了一下go的语法和go的框架,可以读但是还不太会写,然后业务白皮书也看的很头疼,包括landing手册里要了解的很多东西说实话我看文档真的快看死了,一个嵌套一个,问题是我还完全不知道咋用这个我了解的东西,还有就是那个项目代码,那个老哥喊我去写写单测,熟悉一下go的语法,但也进行的很困难(这是我第一段实习,之前都是springboot那一套,真不太熟悉这个)想问问大家的建议,就是我从现在开始到在开年回来之前应该做些什么,我目前就一个想法&nbsp;就是复现一个landing手册上的go框架小项目&nbsp;就是相当于帮自己锻炼锻炼怎么写go&nbsp;或者各位大佬有没有更好的锻炼go语法的建议还有就是大家都在说vibe&nbsp;coding,那我应该怎么锻炼自己使用ai的能力,感觉我除了给一些需求然后它给我生成代码,好像就没别的用法了,那些什么工作流、拆解、skill啥的都不知道从哪一个地方开始,包括我现在正在实习,不知道精力该怎么分配,去网上想找找关于agent开发的一些学习流程,说实话,众说纷纭,有的是从python开始打基础然后系统学那些rag&nbsp;prompt&nbsp;langchain&nbsp;mcp等等,有的是说直接找一个github上的ai项目然后反复问ai,我确实有点迷茫,恳求各位大佬能留下你们宝贵的建议,我一定认真反复深刻学习有一说一&nbsp;我觉得字节饭挺好吃的!
Jasonnnnnn...:直接把项目代码喂给AI然后让它帮你分析,如果组里已经有一些流程图总结的话最好,没有的话自己画一个 Go的话其实只要把基础语法搞明白就行了,项目里很多都是直接让ai帮你写好然后自己稍微改下,不用学的特别深 ai的话,可以自己写一些md文件来搞点小东西,但除非你打算转算法,否则不用把rag langchain学的特别深,了解下就行了
字节跳动公司福利 1371人发布
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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