《算法竞赛从入门到国奖》算法基础:入门篇-模拟

💡Yupureki:个人主页

✨个人专栏:《C++》 《算法》


🌸Yupureki🌸的简介:


目录

前言:

[1. 多项式输出](#1. 多项式输出)

算法原理

实操代码

[2. 蛇形方阵](#2. 蛇形方阵)

算法原理

实操代码

[3. 字符串的展开](#3. 字符串的展开)

算法原理

实操代码


前言:

模拟,顾名思义,就是题目让你做什么你就做什么,考察的是将思路转化成代码的代码能力。 这类题⼀般较为简单,属于竞赛里面的签到题(但是,万事无绝对,也有可能会出现让人非常难受的 模拟题),我们在学习语法阶段接触的题,大多数都属于模拟题。

1. 多项式输出

题目链接:

P1067 [NOIP 2009 普及组] 多项式输出 - 洛谷

算法原理

很简单的模拟题,但有几个小细节需要注意

  1. 如果系数为1或者-1需要省略1这个数字
  2. 最高项的系数如果为正则需要省略+号
  3. 次方如果为1需要省略
  4. 次方如果为0直接输出常数,即系数
  5. 系数如果为0直接跳过该项

实操代码

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

int main()
{
    int n; 
    cin >> n;
    bool first = true;//标记最高项
    
    for (int i = n; i >= 0; i--)//从最高项到最低项输出
    {
        int a; 
        cin >> a;
        
        if (a == 0) continue;//系数为0直接跳过
        
        //输出正负号
        if (first)
        {
            if (a < 0) cout << "-";
        }
        else
        {
            if (a > 0) cout << "+";
            else cout << "-";
        }
        
        //输出系数和x的幂
        int abs_a = abs(a);
        
        if (i == 0)//如果是x的0次方直接输出系数
        {
            cout << abs_a;
        }
        else if (i == 1)//如果是x的1次方省略幂
        {
            if (abs_a == 1)//如果系数为1省略
                cout << "x";
            else
                cout << abs_a << "x";
        }
        else
        {
            if (abs_a == 1)
                cout << "x^" << i;
            else
                cout << abs_a << "x^" << i;
        }
        
        first = false;
    }
    if (first) cout << "0";//如果多项式不存在直接输出0
    return 0;
}

2. 蛇形方阵

题目链接:

P5731 【深基5.习6】蛇形方阵 - 洛谷

算法原理

从1到n的分布是从外圈到内圈的,如果无脑套循环的话其实并不好做

那么在此我们引入一个新的方式 即方向向量

cpp 复制代码
int dx[] ={1,0,-1,0};
int dy[] ={0,1,0,-1};

我们仔细分析可发现 数字的递增方式无非是向右,向左,向上或者向下四个方向

例如从1到4一直是向右,从4到7一直是向下以此类推

那么我们定义dx和dy两个数组,dx代表横坐标的增加量,dy表示纵坐标的增加量

如果我们把数组的左上角,即1这个位置定义为原点,行表示x轴,列表示y轴

那么对应的dx[n] 和dy[n]就表示一个方向向量,例如dx[0] 和dy[0]表示列+1,行不变,即向右移动一格,以此类推

这样我们就能灵活地控制上下左右的移动了。一开始肯定是从1向右移动到4,如果移动到5那么就越界了,转变方向到向下,从4到7,到7这个位置就再次转变方向到向上,这个时候最后会遇见1,我们要重新转变方向到向右。

因此我们转换方向的方式可以设置为,当前位置超过数组范围,或者这个格子已经填充了,那么就转变方向

实操代码

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

int dx[] ={1,0,-1,0};//方向向量
int dy[] ={0,1,0,-1};

int arr[10][10] = {0};

int main()
{
    int n;cin>>n;
    int num = 1;
    int pos = 0;
    int x = 1;int y = 1;
    while(num<=n*n)//自动填充数组
    {
        arr[y][x] = num;
        int a = x + dx[pos];
        int b = y + dy[pos];
        if(a<1||a>n||b<1||b>n||arr[b][a] != 0)//转变方向
        {
            pos = (pos+1)%4;
            a = x + dx[pos];
            b = y + dy[pos];
        }
        x = a;y = b;
        num++;
    }
    for(int i = 1;i<=n;i++)
    {
        for(int j = 1;j<=n;j++)
        {
            printf("%3d",arr[i][j]);
        }
        cout<<endl;
    }
    return 0;
}

3. 字符串的展开

题目链接:

P1098 [NOIP 2007 提高组] 字符串的展开 - 洛谷

算法原理

根据规则展开字符串即可

题目给出的展开规则十分详细,只需要注意小细节,分类讨论即可

实操代码

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

int pos1,pos2,pos3;

string add(char left, char right)//展开函数
{
    string ret;
    for (char i = left + 1; i < right; i++)遍历中间的字符
    {
        char ch = i;
        if (pos1 == 2 && isalpha(ch))
            ch = toupper(ch);//小写变大写
        else if (pos1 == 3)
            ch = '*';
        for (int i = 0; i < pos2; i++)
        {
            ret += ch;
        }
    }
    if (pos3 == 2)//判断是否倒置
        reverse(ret.begin(), ret.end());
    return ret;
}

int main()
{
    string ret;
    cin >> pos1 >> pos2 >> pos3;
    string s;
    cin >> s;
    for (int i = 0; i < s.size(); i++)
    {
        if (s[i] != '-' || i == 0 || i == s.size() - 1)
            ret += s[i];
        else
        {
            if (isalpha(s[i - 1]) && isalpha(s[i + 1]) && s[i+1] >s[i-1] ||
                isdigit(s[i - 1]) && isdigit(s[i + 1]) && s[i+1] >s[i-1])//判断是否展开
                ret += add(s[i - 1], s[i + 1]);//展开
            else
                ret += s[i];
        }
    }
    for (auto& it : ret)
    {
        cout << it;
    }
    return 0;
}
相关推荐
长安er3 小时前
LeetCode215/347/295 堆相关理论与题目
java·数据结构·算法·leetcode·
元亓亓亓3 小时前
LeetCode热题100--62. 不同路径--中等
算法·leetcode·职场和发展
小白菜又菜3 小时前
Leetcode 1925. Count Square Sum Triples
算法·leetcode
粉红色回忆4 小时前
用链表实现了简单版本的malloc/free函数
数据结构·c++
登山人在路上4 小时前
Nginx三种会话保持算法对比
算法·哈希算法·散列表
写代码的小球5 小时前
C++计算器(学生版)
c++·算法
AI科技星5 小时前
张祥前统一场论宇宙大统一方程的求导验证
服务器·人工智能·科技·线性代数·算法·生活
k***92165 小时前
【C++】继承和多态扩展学习
java·c++·学习
予枫的编程笔记5 小时前
Redis 核心数据结构深度解密:从基础命令到源码架构
java·数据结构·数据库·redis·缓存·架构
wadesir5 小时前
掌握Rust并发数据结构(从零开始构建线程安全的多线程应用)
数据结构·安全·rust