算法学习入门---模拟(C++)

目录

1.洛谷---多项式输出

2.洛谷---蛇形方阵

3.洛谷---字符串展开


1.洛谷---多项式输出

一项一项输出,每一项输出关心3个部分:符号+系数+次数

  1. 符号:其他时间不用管,除了第一次输出,如果为正则跳过输出,为负正常输出
  2. 系数:为 1 时跳过输出,当次数为 0 时,即使为 1 也要正常输出;为 0 时符号一整段跳过输出(break语句)
  3. 次数:第一个未知数的次数为 n
  4. 当输出完符号后,系数的符号就没用了,所以可以abs取系数的绝对值
  5. 字符串变量不能和整型变量相加,c++中未定义过这样的操作

代码:

cpp 复制代码
#include<iostream>
#include<vector>
#include<string>
#include<cmath>
using namespace std;

string ret;

int main()
{
	int n;cin>>n;
	vector<int> num(n+1,0);
	for(int i=n;i>=0;i--)cin>>num[i];
	for(int i=n;i>=0;i--)
	{
		//系数为0,什么都不用考虑了 
		if(!num[i]) continue;
		else
		{
			//符号判断  
			if(num[i]<0) ret+='-';
			else
			{
				if(i!=n) ret+='+';
			}
			//系数判断
			int flag = abs(num[i]);
			if(flag!=1||(flag==1&&i==0)) ret+=to_string(flag);
			//次数判断
			if(i>1) ret = ret + "x^" + to_string(i);
			else if(i==1) ret += "x";
		} 
	}
	cout<<ret;
	return 0;
}

代码易错点:

请注意,x的次数为1时,是不需要加上 ^1 的!

2.洛谷---蛇形方阵

注意事项:注意每个数字有都会占用 3 个字符,前面使用空格补齐

解决思路:

  1. 定义方向向量:先定义一个坐标轴,因为原点是在左上角,所以需要把整个坐标轴往右旋转90°,如下图1所示;定义两个数组,dx 和 dy ,dx = {0,0,1,-1} dy = {1,-1,0,0} ;此时如果从(2,3)往右走一个单位 -> (2,4)= (2,3)+ dx[0] + dy[0]
  2. 根据规则结合方向向量填数:朝一个方向走,边走边填数;越界之后,结合方向向量,重新计算出新的坐标以及方向
  3. 数组从第1行第1列开始算,这样就可以简化很多的数组越界问题
  4. 边界情况:y <= n && x <= n && x >= 1 && y >= 1 && arr[x][y] == 0
  5. dx、dy数组最好是以右下左上的顺序出现,并定义一个变量pos,只要不符合上面的边界情况,pos ++;但如果 pos 从最后一个的情况(往上移动,如下图2所示),变回了第1种情况(往右移动),此时数组会越界,所以需要 pos = (pos+1)%4
  6. 总共要填n行n列个数字,即为 n * n 个数字
  7. %0 /0 不会编译报错,但在C++中这是未定义行为,通常会导致程序崩溃或死循环

图1

图2

代码:

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;

const int N = 30;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};//右下左上
int ret[N][N];

int main()
{
	int n;
	cin>>n;
	int x=1,y=1;//初始位置
	int count=1;//当前数值 
	int pos = 0;

	while(count<=n*n)
	{
		//正常情况 
		if(y >= 1 && y <= n && x <= n && x >= 1 && ret[x][y] == 0) ret[x][y]=count;
		else//越界情况 
		{
			x-=dx[pos];y-=dy[pos];//出现越界了还要退回到原来位置 
			pos = (pos+1)%4; 
			count--;//字符还没有填,所以需要和后面那个count++抵消掉 
		} 
		x+=dx[pos];y+=dy[pos];
		count++;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			printf("%3d",ret[i][j]); 
		cout<<endl;
	}
	return 0;	
} 

代码易错点:

如何输出占用3个字符的数字?

printf("%3d",ret[i][j]);

3.洛谷---字符串展开

对于条件很多的模拟题,我们可以把各种条件先写下来

  • p1 : =1 -> 填小写 && =2 -> 填大写 && =3 -> 填 * 号
  • p2 : =1 -> 填 1 个 && =n -> 填 n 个
  • p3 : =1 -> 顺序填写 && =2 -> 逆序填写

同时还有一些注意事项:

当 - 号两边只差了1(例如d和e),那么直接把 - 号去掉就行;当 - 号两边为同一个字符,那么直接原封不动地输出 - 号;如果 - 号左边的字符大于右边的字符,也是直接输出 - 号;当不为 - 号,直接输出即可,因为需要修改填充的只有 - 号;当 - 号出现在字符串开头和结尾,直接输出

代码:

cpp 复制代码
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int p1,p2,p3;
string a;
string ret;

bool islet(char ch)
{
	return ch>='a'&&ch<='z'; 
}

bool isnum(char ch)
{
	return ch>='0'&&ch<='9';
}

void add(char left,char right)
{
	//开始展开
	string r;
	for(char ch=left+1;ch<right;ch++)
	{
		char tmp = ch;
		//处理p1
		if(p1==2&&islet(tmp)) tmp-=32;
		else if(p1==3)tmp = '*';
		//处理p2
		for(int turn=1;turn<=p2;turn++)r+=tmp;  
	} 
	//处理p3 
	if(p3==2)reverse(r.begin(),r.end());
	ret+=r;
}

int main()
{
	cin>>p1>>p2>>p3>>a;
	int n = a.size();
	for(int i=0;i<=n-1;i++)
	{
		//不是 - 号,或者 - 号出现在开头和结尾
		if(a[i]!='-'||i==0||i==n-1)  ret+=a[i];
		else
		{
			char left=a[i-1],right=a[i+1];
			//islet函数为判断字符是否为字母,isnum函数为判断字符是否为数字 
			if((islet(left)&&islet(right)&&right>left)||
			    (isnum(left)&&isnum(right)&&right>left))
			    {
			    	//字符串展开
					add(left,right); 
				}
			else
			{
				ret+=a[i];
			}
		}
	}
	cout<<ret;
	return 0;
}

代码易错点:

写这种模拟题真的会有非常多的条件需要判断,因此我们可以通过函数来进行模块的解耦,最好不要出现屎山代码(会难以调试与理解)

当我们直接cout (a-a+A)时,输出的不会是字符A,而是A的asc码值65

小写字母变大写字母,减去32号即可(a的asc码为97,A的asc码为65)

相关推荐
夜月yeyue1 小时前
嵌入式开发中的 Git CI/CD
c++·git·单片机·嵌入式硬件·ci/cd·硬件架构
搂鱼1145141 小时前
GJOI 11.10 题解
算法
爱睡觉的咋1 小时前
openGauss × AI:打造一个能识图、能讲解、还能推荐的智慧博物馆导览师
算法
编程之路,妙趣横生2 小时前
类和对象(下)
c++
视觉AI2 小时前
一帧就能“训练”的目标跟踪算法:通俗理解 KCF 的训练机制
人工智能·算法·目标跟踪
2301_795167202 小时前
玩转Rust高级应用 如何理解 Rust 实现免疫数据竞争的关键是Send 和 Sync 这两个 trait
开发语言·算法·rust
Blossom.1182 小时前
AI Agent记忆系统深度实现:从短期记忆到长期人格的演进
人工智能·python·深度学习·算法·决策树·机器学习·copilot
Q741_1473 小时前
C++ 面试高频考点 链表 迭代 递归 力扣 25. K 个一组翻转链表 每日一题 题解
c++·算法·链表·面试·递归·迭代
syker3 小时前
手搓UEFI.h
c++