模拟题刷题1

目录

[P1003 [NOIP 2011 提高组] 铺地毯](#P1003 [NOIP 2011 提高组] 铺地毯)

[P1067 [NOIP 2009 普及组] 多项式输出](#P1067 [NOIP 2009 普及组] 多项式输出)

[P1328 [NOIP 2014 提高组] 生活大爆炸版石头剪刀布](#P1328 [NOIP 2014 提高组] 生活大爆炸版石头剪刀布)

[P1563 [NOIP 2016 提高组] 玩具谜题](#P1563 [NOIP 2016 提高组] 玩具谜题)

[P1042 [NOIP 2003 普及组] 乒乓球](#P1042 [NOIP 2003 普及组] 乒乓球)

[P1179 [NOIP 2010 普及组] 数字统计](#P1179 [NOIP 2010 普及组] 数字统计)

[P2615 [NOIP 2015 提高组] 神奇的幻方](#P2615 [NOIP 2015 提高组] 神奇的幻方)

[P3952 [NOIP 2017 提高组] 时间复杂度](#P3952 [NOIP 2017 提高组] 时间复杂度)

[P2482 [SDOI2010] 猪国杀](#P2482 [SDOI2010] 猪国杀)

[P5380 [THUPC 2019] 鸭棋](#P5380 [THUPC 2019] 鸭棋)


P1003 [NOIP 2011 提高组] 铺地毯

一开始用很大的数组存储所有地毯的信息,时间和空间太大了,最后MLE

可以换一种思路:把信息存储起来,先读入要找的坐标,确认坐标后,再挨个找之前存储的地毯中覆盖该坐标的地毯的编号

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
int main(){
    int n;
    cin>>n;
    vector<vector<int>> s(n,vector<int>(4));
    int x,y;
    for(int i=0;i<n;i++){
        for(int j=0;j<4;j++){
            cin>>s[i][j];
        }
    }
    cin>>x>>y;
    int ans=-1;
    for(int i=0;i<n;i++){
        int x_left_bottom=s[i][0];
        int y_left_bottom=s[i][1];
        int x_right_top=s[i][0]+s[i][2];
        int y_right_top=s[i][1]+s[i][3];
        if(x>=x_left_bottom&&x<=x_right_top&&y>=y_left_bottom&&y<=y_right_top)ans=i+1;
    }
    cout<<ans;
    return 0;
}

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

有很多坑

1、x的次数,如果是1,那么"^1"是不用写的

2、如果数字1在x前面,不用写,如果是常数,要写

3、注意转化方法

int转string:to_string();

string转int:stoi();

用s存储答案,是因为考虑到了输入全是0的情况,可惜后来发现题目中明确说明不能全是0,所以写了也没啥用了

注意读题!!!

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
int main()
{
    int n;
    cin >> n;
    string s = "";
    for (int i = 0; i <= n; i++)
    {
        int t;
        cin >> t;
        if (t > 0)
        {
            if (i != 0)s += '+';
            if (n - i != 0)
            {
                if (t != 1)s += to_string(t);
                s += 'x';
                if (n - i != 1)
                {
                    s += '^';
                    s += to_string(n - i);
                }
            }
            else s += to_string(t);
        }
        else if (t < 0)
        {
            s += '-';
            if (n - i != 0)
            {
                if (t != -1)s += to_string(-t);
                s += 'x';
                if (n - i != 1)
                {
                    s += '^';
                    s += to_string(n - i);
                }
            }
            else s += to_string(-t);
        }
    }
    if (s.size() == 0)cout << 0;
    else cout << s;
    return 0;
}

P1328 [NOIP 2014 提高组] 生活大爆炸版石头剪刀布

匹配很复杂,一开始画了一张图对应,分情况讨论

后来发现可以存二维数组(把结果存进去)

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
vector<int> a, b;
int n;
int A, B;
int scoreA, scoreB;
void solve(int x, int y)
{
    if (x == y)
        return;
    if (x == 0)
    {
        if (y == 2 || y == 3)
        {
            scoreA++;
            return;
        }
    }
    else if (x == 1)
    {
        if (y == 0 || y == 3)
        {
            scoreA++;
            return;
        }
    }
    else if (x == 2)
    {
        if (y == 1 || y == 4)
        {
            scoreA++;
            return;
        }
    }
    else if (x == 3)
    {
        if (y == 2 || y == 4)
        {
            scoreA++;
            return;
        }
    }
    else if (x == 4)
    {
        if (y == 0 || y == 1)
        {
            scoreA++;
            return;
        }
    }
    scoreB++;
}
int main()
{
    cin >> n >> A >> B;
    a.resize(A);
    b.resize(B);
    for (int i = 0; i < A; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < B; i++)
    {
        cin >> b[i];
    }
    int pA = 0;
    int pB = 0;
    while (n--)
    {
        solve(a[pA], b[pB]);
        pA++;
        pB++;
        if (pA == A)
            pA = 0;
        if (pB == B)
            pB = 0;
    }
    cout << scoreA << " " << scoreB;
    return 0;
}

优化:

注意vector初始化方法

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int x, y;
int main()
{
    int n, a, b;
    cin >> n >> a >> b;
    vector<int> A(a);
    vector<int> B(b);
    for (int i = 0; i < a; i++)
    {
        cin >> A[i];
    }
    for (int i = 0; i < b; i++)
    {
        cin >> B[i];
    }
    vector<vector<int>> gra = {{0, 0, 1, 1, 0},
                               {1, 0, 0, 1, 0},
                               {0, 1, 0, 0, 1},
                               {0, 0, 1, 0, 1},
                               {1, 1, 0, 0, 0}};
    for (int i = 0; i < n; i++)
    {
        x += gra[A[i % a]][B[i % b]];
        y += gra[B[i % b]][A[i % a]];
    }
    cout << x << " " << y;
    return 0;
}

P1563 [NOIP 2016 提高组] 玩具谜题

两个数字,不同时向右走,相同时向左走

注意向左走时可能是负数,代码可以写成p = (p % n + n) % n;

原来用一个二维string数组存数据,卡了很久,其实可以用两个数组来存

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int n, m;
    cin >> n >> m;
    vector<vector<string>> s(n, vector<string>(2));
    for (int i = 0; i < n; i++)
    {
        cin >> s[i][0] >> s[i][1];
    }
    int a, k;
    int p = 0;
    while (m--)
    {
        cin >> a >> k;
        k %= n;
        if ((s[p][0] == "1" && a == 0) || (s[p][0] == "0" && a == 1))
        {
            p += k;
        }
        else
        {
            p -= k;
        }
        p = (p % n + n) % n;
    }
    cout << s[p][1];
    return 0;
}

优化:

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int n, m;
    cin >> n >> m;
    vector<int> num(n);
    vector<string> job(n);
    for (int i = 0; i < n; i++)
    {
        cin >> num[i] >> job[i];
    }
    int a, k;
    int p = 0;
    while (m--)
    {
        cin >> a >> k;
        k %= n;
        if (num[p] == a)
        {
            p -= k;
        }
        else
        {
            p += k;
        }
        p = (p % n + n) % n;
    }
    cout << job[p];
    return 0;
}

P1042 [NOIP 2003 普及组] 乒乓球

这道题目看起来有点怪

1、题目中并没有明确说胜利条件是当有一方分数>=11且比对方高>=2分时。举的例子也是11:0、21:0之类的,我误以为只要进行11局或21局,最后得分高者胜利。

2、注意:当一局比赛结束后,下一局立刻开始。这句话我没理解是什么意思。

题目想提醒的应该是最后当x和y都是0时也要输出(写了同时是0的判断条件后WA了好多),但是我没理解这行代码跟题目的提醒有什么关系。

不知道是我的理解能力差,还是题目真的有点误导人?

如果题目改一下描述思路就会清楚很多

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    char t;
    vector<int> s;
    while (cin >> t)
    {
        if (t == 'E')
        {
            break;
        }
        if (t == 'W')
        {
            s.push_back(1);
        }
        else
        {
            s.push_back(0);
        }
    }
    int x = 0;
    int y = 0;
    for (int i : s)
    {
        if (i)
        {
            x++;
        }
        else
        {
            y++;
        }
        if (max(x, y) >= 11 && abs(x - y) >= 2)
        {
            cout << x << ":" << y << endl;
            x = 0;
            y = 0;
        }
    }
    cout << x << ":" << y << endl;
    x = 0;
    y = 0;
    cout << endl;
    for (int i : s)
    {
        if (i)
        {
            x++;
        }
        else
        {
            y++;
        }
        if (max(x, y) >= 21 && abs(x - y) >= 2)
        {
            cout << x << ":" << y << endl;
            x = 0;
            y = 0;
        }
    }
    cout << x << ":" << y << endl;
    return 0;
}

P1179 [NOIP 2010 普及组] 数字统计

left和right不能写在全局变量中

在 C++ 标准库里(以及某些编译器/IDE 预编译头里),有一些东西叫 std::left / std::right ------它们是 iostream 的"对齐格式控制器"(比如 cout << left << setw(10) 这种)。

当你写了:

using namespace std; int left, right;

你的全局变量名 left/right 会和 std::left/std::right 发生冲突。IDE 的语义检查器(尤其是 VSCode 的 IntelliSense / clangd)就可能报:

"left" 不明确 / "right" 不明确

因为它看到 left 时,不确定你指的是全局变量还是 std::left 操纵符。

cpp 复制代码
#include <iostream>
using namespace std;
int ans;
int L, R;
int main()
{
    cin >> L >> R;
    for (int i = L; i <= R; i++)
    {
        int t = i;
        while (t)
        {
            if (t % 10 == 2)
            {
                ans++;
            }
            t /= 10;
        }
    }
    cout << ans;
    return 0;
}

P2615 [NOIP 2015 提高组] 神奇的幻方

很简单的模拟,按照题意写即可

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int n;
    cin >> n;
    vector<vector<int>> s(n, vector<int>(n));
    s[0][n / 2] = 1;
    int x = 0;
    int y = n / 2;
    for (int k = 2; k <= n * n; k++)
    {
        if (x == 0 && y != n - 1)
        {
            x = n - 1;
            y = y + 1;
        }
        else if (y == n - 1 && x != 0)
        {
            y = 0;
            x = x - 1;
        }
        else if (x == 0 && y == n - 1)
        {
            x = x + 1;
        }
        else if (x != 0 && y != n - 1)
        {
            if (s[x - 1][y + 1] == 0)
            {
                x = x - 1;
                y = y + 1;
            }
            else
            {
                x = x + 1;
            }
        }
        s[x][y] = k;
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cout << s[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

P3952 [NOIP 2017 提高组] 时间复杂度

用栈模拟

好难的模拟题

P2482 [SDOI2010] 猪国杀

P5380 [THUPC 2019] 鸭棋

相关推荐
亲爱的非洲野猪2 小时前
1动态规划入门:从斐波那契到网格路径
算法·动态规划
zhangfeng11332 小时前
大语言模型 bpe算法 后面对接的是 one-hot吗 nn.Embedding
算法·语言模型·embedding
Pluchon2 小时前
硅基计划4.0 算法 动态规划高阶
java·数据结构·算法·leetcode·深度优先·动态规划
科学计算技术爱好者3 小时前
NVIDIA GPU 系列用途分类梳理
人工智能·算法·gpu算力
程序员敲代码吗3 小时前
嵌入式C++开发注意事项
开发语言·c++·算法
好学且牛逼的马3 小时前
【Hot100|14-LeetCode53. 最大子数组和】
数据结构·算法·leetcode
无心水3 小时前
17、Go协程通关秘籍:主协程等待+多协程顺序执行实战解析
开发语言·前端·后端·算法·golang·go·2025博客之星评选投票
东华果汁哥3 小时前
【机器视觉 行人检测算法】FastAPI 部署 YOLO 11行人检测 API 服务教程
算法·yolo·fastapi
每天学一点儿3 小时前
[SimpleITK] 教程 63:配准初始化 (Registration Initialization) —— 从几何对齐到手动干预。
算法