一.蛇形方阵
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;
}
以上就是我们今天的内容,本节和上一节均属于模拟题,这类题目在算法竞赛中往往比较简单,属于签到题,感兴趣的朋友们可以一键三连喔~