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

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

相关推荐
老鱼说AI12 小时前
CUDA架构与高性能程序设计:异构数据并行计算
开发语言·c++·人工智能·算法·架构·cuda
罗湖老棍子12 小时前
【例 1】数列操作(信息学奥赛一本通- P1535)
数据结构·算法·树状数组·单点修改 区间查询
big_rabbit050213 小时前
[算法][力扣222]完全二叉树的节点个数
数据结构·算法·leetcode
张李浩13 小时前
Leetcode 15三题之和
算法·leetcode·职场和发展
2301_7938046914 小时前
C++中的适配器模式变体
开发语言·c++·算法
x_xbx14 小时前
LeetCode:206. 反转链表
算法·leetcode·链表
abant214 小时前
leetcode 138 复制随机链表
算法·leetcode·链表
ab15151714 小时前
3.17二刷基础112 118 完成进阶52
数据结构·算法
旖-旎14 小时前
二分查找(1)
c++·算法·二分查找·力扣·双指针
困死,根本不会15 小时前
【C 语言】指针学习笔记:从底层原理到实战应用
c语言·开发语言·笔记·学习·算法