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

一.蛇形方阵

1.题目:

2.讲解算法原理:

解法:模拟填数过程即可

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

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

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

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

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

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

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

疑问一:如何处理越界?

根据如图所示,可以分析:当y>n或者x>n或者x<1或者arrxy!=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;
 } 

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

相关推荐
.道阻且长.10 小时前
2.LeetCode算法习题讲解--双指针--复写零
算法·leetcode·职场和发展
To_OC12 小时前
LC 438 找到所有字母异位词:暴力超时后,我靠滑动窗口一招搞定
javascript·算法·leetcode
Forever Nore14 小时前
学完C语言力扣第一题做不来正常吗
数据结构·算法
hansang_IR15 小时前
【题解】LC:倍增 / 区间并查集(Range Parallel Unionfind)
c++·算法·并查集
Tisfy16 小时前
LeetCode 3731.找出缺失的元素:哈希 / 排序
算法·leetcode·哈希算法·排序·哈希表
lucas_AI17 小时前
Q-CueGraph:你的多模态大模型会 zoom,但真的知道该看哪儿吗?
人工智能·算法
kaixin_啊啊17 小时前
test_机器学习算法学习
学习·算法·机器学习
liulilittle17 小时前
MOE路由:路由(logits: top-k/8)
c++·人工智能·算法·机器学习·llm
旖旎夜光17 小时前
LeetCode 11:盛最多水的容器(双指针问题) —— 题解
数据结构·c++·算法·leetcode·双指针