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;
 } 

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

相关推荐
如何取名5 分钟前
结合实际业务进行LRU淘汰算法优化设计(数据库开发日志)
数据库·算法
aichitang20249 分钟前
快乐泛函每一天:希尔伯特空间中的最佳逼近与正交投影定理
人工智能·考研·算法·ai·面试·泛函分析
淬炼之火14 分钟前
笔记:Visually-Guided Policy Optimization for Multimodal Reasoning
人工智能·笔记·算法·机器学习·语言模型·自然语言处理
一只QAQ16 分钟前
c++项目
java·c++·算法
学习星球20 分钟前
空天地一体化网络(NTN)深度解析:从Starlink D2C到3GPP NTN,卫星直连手机是如何实现的?
网络·人工智能·算法·智能手机·php
科技林总31 分钟前
提示词测评落地全流程
人工智能·算法
晴天的雨.9921 小时前
类和对象下(内部类,匿名对象,对象拷贝时的编译器优化)
开发语言·c++·算法
旖旎夜光1 小时前
LeetCode 238:除自身以外数组的乘积(前缀和) —— 题解
数据结构·c++·算法·leetcode·前缀和
一条大祥脚1 小时前
26杭电暑期第八场(后半)快读|快写|tarjan|路径DP|mex转化|扫描线|前缀和|二分图
数据结构·算法·tarjan·杭电多校·强联通分量·动态规划dp
奈斯先生Vector1 小时前
从“能调用”到“可运营”:AI Agent 进入多模型时代后的架构升级
java·javascript·数据库·人工智能·算法·架构·aigc