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

💡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;
}
相关推荐
wen__xvn20 分钟前
基础算法集训第01天:线性枚举
数据结构·c++·算法
nju_spy22 分钟前
力扣每日一题 2026.1
算法·leetcode·二分查找·动态规划·最小生成树·单调栈·最长公共子序列
Howrun77732 分钟前
C++ 线程互斥锁 lock_guard
c++·算法
小李独爱秋32 分钟前
计算机网络经典问题透视:试比较先进先出排队(FIFO)、公平排队(FQ)和加权公平排队(WFQ)的优缺点
服务器·计算机网络·算法·web安全·信息与通信·队列
代码游侠32 分钟前
ARM嵌入式开发代码实践——LED灯闪烁(C语言版)
c语言·开发语言·arm开发·笔记·嵌入式硬件·学习
永远都不秃头的程序员(互关)38 分钟前
【K-Means深度探索(十)】进阶思考:K-Medoids与Fuzzy C-Means,K-Means的“亲戚”们!
算法·机器学习·kmeans
Remember_99339 分钟前
【LeetCode精选算法】二分查找专题一
java·数据结构·算法·spring·leetcode·哈希算法
刘某某.42 分钟前
大模型数据传输3 种方式对比
算法
橘子师兄44 分钟前
C++AI大模型接入SDK—快速上手
开发语言·c++·人工智能
麒qiqi1 小时前
进阶 IMX6ULL 裸机开发:从 C 语言点灯到 BSP 工程化(附 SDK / 链接脚本实战)
c语言·开发语言