002【模拟】--蛇形方阵、字符串展开

一.蛇形方阵

1.题目:

2.讲解算法原理:

解法:模拟填数过程即可

实现的方式有很多种,这里给大家介绍一种通用的解法---解决矩阵中填数的题目

1)定义方向向量:先定义两个数组dx,dy,这两个数组中同一位置所对应的两个数是配套使用的,表示向哪个方向走,如下图所示:

其中,"右下左上"为题目中所给的"顺时针"方向。

2)根据规则结合方向向量填数:

①朝一个方向走,一边走一边填数,直到越界为止。

②越界之后,结合方向向量,重新计算出新的坐标及方向。

注:一般矩阵或者数组喜欢从下标为1开始,这是为了更好的处理边界越界的情况,但是万事无绝对,大多数情况还是下标从1开始比较好。

疑问一:如何处理越界?

根据如图所示,可以分析:当y>n或者x>n或者x<1或者arr[x][y]!=0时,会越界。

疑问二:如何重新计算出新的坐标及方向?

pos=(pos+1)%4,pos为指向当前数组的指针。

3.代码

cpp 复制代码
#include <iostream>
using namespace std;
const int N=15;
//定义两个方向向量 
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int arr[N][N];
int main()
{
	int n;
	cin>>n;
	//模拟填数过程
	int x=1,y=1;//初始位置
	int pos=0;
	int cnt=1;//第一个位置要填的数
	while(cnt<=n*n)
	{
		arr[x][y]=cnt;
		//计算下一个位置
		int a=x+dx[pos],b=y+dy[pos];
		//判断是否越界 
		if(a>n||b>n||a<1||b<1||arr[a][b]!=0)
		{
			//更新出应该走的正确位置
			pos=(pos+1)%4;
			a=x+dx[pos],b=y+dy[pos];
		 } 
		 x=a,y=b;
		 cnt++;
	 } 
	 //输出
	 for(int i=1;i<=n;i++)
	 {
	 	for(int j=1;j<=n;j++)
	 	{
	 		printf("%3d",arr[i][j]);
		 }
		 printf("\n");
	  } 
	return 0;
}

二.字符串展开

1.题目:

2.讲解算法原理:

本题只要题意读懂,纯纯考察代码能力,我们可以先把总体框架写出来,里面用到的每一个函数功能的实现可以封装成一个函数。

3.代码

cpp 复制代码
#include <iostream>
#include <algorithm>
using namespace std;
int p1,p2,p3,n;
string s;
string ret;
//判断是否是数字字符
bool isdig(char ch)
{
	return ch>='0'&&ch<='9';
 } 
//判断是否是小写字母
bool islet(char ch)
{
	return ch>='a'&&ch<='z';
 } 
 //展开left和right中间的数 
 void add(char left,char right)
 {
 	string t;//创建一个中间字符串t,因为后续字符串可能会存在逆序 
 	//遍历中间的字符 
 	for(char ch=left+1;ch<right;ch++)
 	{
 		char tmp=ch;//中间变量tmp存一下ch
		 //先讨论p1
		 if(p1==2&&islet(tmp))  tmp-=32;
		 else if(p1==3) tmp='*';
		 //再弄p2,直接创建一个循环即可
		 for(int i=1;i<=p2;i++)
		 {
		 	t+=tmp;
		 }  
	 }
	 //此时,中间字符全部扩充完毕
	 if(p3==2) reverse(t.begin(),t.end());
	 ret+=t;
  } 
int main()
{
	cin>>p1>>p2>>p3>>s;
	n=s.size();
	for(int i=0;i<n;i++)
	{
		char ch=s[i];
		if(s[i]!='-'||i==0||i==n-1)
		{
			ret+=ch;
		}
		else
		{
			char left=s[i-1],right=s[i+1];
			if(isdig(left)&&isdig(right)&&right>left||islet(left)&&islet(right)&&right>left)
			{
				//展开
				add(left,right); 
			}
			else
			{
				ret+=ch;
			}
		}
	}
	cout<<ret<<endl;
	return 0;
 } 

以上就是我们今天的内容,本节和上一节均属于模拟题,这类题目在算法竞赛中往往比较简单,属于签到题,感兴趣的朋友们可以一键三连喔~

相关推荐
多恩Stone1 小时前
【3DV 进阶-12】Trellis.2 数据处理脚本细节
人工智能·pytorch·python·算法·3d·aigc
wfeqhfxz25887821 小时前
【目标检测系列】:基于YOLOv10n的MAN卡车超载检测系统·结合FasterCGLU与WFU优化算法_1
算法·yolo·目标检测
爱尔兰极光1 小时前
LeetCode 热题 100-连续最长序列
算法·leetcode·职场和发展
生成论实验室1 小时前
生成式通用智能(GAGI):基于《易经》状态空间的认知架构
人工智能·神经网络·算法·架构·信息与通信
We་ct2 小时前
LeetCode 242. 有效的字母异位词:解法解析与时空优化全攻略
前端·算法·leetcode·typescript
执着2592 小时前
力扣hot100 - 104、二叉树的最大深度
算法·leetcode·职场和发展
_OP_CHEN2 小时前
【算法基础篇】(五十四)解析错排问题:从信封错位到编程实战,一次性搞懂排列组合中的 “反常识” 难题!
算法·蓝桥杯·c/c++·组合计数·算法竞赛·acm/icpc·错排问题
苦藤新鸡2 小时前
54 子集
算法·leetcode·动态规划
近津薪荼2 小时前
递归专题5——快速幂
c++·学习·算法