【无标题】

这篇博客讨论了一个涉及栈操作的问题,其中包含了四种不同的操作:压栈、弹栈、查询栈顶元素以及修改栈顶k个元素为它们的最大公约数。在实现过程中,作者通过维护一个额外的数组来存储栈内元素的最大公约数。文章强调了审题和转换思维的重要性,并给出了相应的C++代码实现。
摘要由CSDN通过智能技术生成

栈与公约数

公约数,亦称"公因数"。

它是指能同时整除几个整数的数。如果一个整数同时是几个整数的约数,称这个整数为它们的"公约数"。

公约数中最大的称为最大公约数。

初始有一个为空的栈,进行q次操作,操作分为以下四种:

1.在栈顶放入一个元素x

2.删除栈顶元素(数据保证此时栈内至少有一个元素)

3.查询栈顶元素

4.将栈顶的k个元素修改成他们的最大公约数(数据保证k不超过栈中元素数量)(比如栈内元素是4,2,将栈顶的2个元素修改成他们的最大公约数,栈内元素是2,2)

输入描述:
第一行一个正整数q,

接下来的q行,每行包括一到两个整数,第一个整数op表示操作类型:

当op = 1时,该行会有第二个整数x,表示在栈顶放入元素x

当op = 2时,该行只有一个整数op,表示删除此时栈顶的元素(数据保证此时栈内至少有一个元素)

当op = 3时,该行只有一个整数op,此时你需要输出栈顶的元素

当op = 4时,该行会有第二个整数k,表示在将栈顶的k个元素修改成他们的最大公约数(数据保证k不超过栈中元素数量)

对于100%的数据,1 <= q <= 200000,1 <= x <= 100000000
输出描述:
对于每个op = 3的询问,分别输出一行y,表示此时栈顶的元素
示例1
输入
11
1 2
1 3
3
4 2
3
2
1 2
4 2
3
2
3
输出
3
1
1
1

总结:题不难,但是为什么没有做出来?
1.审题不细心,题目操作4的意思是 让栈顶k个元素换成栈内所有数的最大公寓数。
2.wa了几发后还不知道转换思维

思路:用一个数组去维护栈内数的最大公约数 即b[k]表示栈内有栈底开始的k个数的最大公约数

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2e5+10;
int a[N], b[N];
int gcd(int a, int b)
{
    return b? gcd(b, a % b):a;
}
int main()
{
    int q, op, x, hh = 0;
    cin >> q;
    while(q --)
    {
        cin >> op;
        if(op == 1)
        {
            cin >> x;
            a[++ hh] = x;
            if(hh == 1)
                b[hh] = x;
            else
                b[hh] = gcd(b[hh - 1], x); //没存储一个数就存储栈内k个数的最大公约数
        }
        else if(op == 2)
            hh --;
        else if(op == 3)
            cout << a[hh] << endl;
        else
        {
            cin >> x;
            int p = b[hh], q = gcd(b[hh], b[hh - x]);//b[hh]表示栈内所有元素的最大公约数
    //现要将栈顶k个元素换成b[hh], 所以栈内前hh-x的最大公约数不变,但是后第hh-x+1个元素加入后
    // 栈内所有数的最大公约数就变成了gcd(b[hh], b[hh-x]);
            for(int i = hh - x + 1; i <= hh; i ++)
                a[i] = p, b[i] = q;
        }
            
    }
    return 0;;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值