2022 年辽宁省大学生程序设计竞赛 G题(栈与公约数)题解

题目链接

牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ

题目描述

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

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

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

初始有一个为空的栈,进行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

这道题的大体思路就是手写一个栈,入栈,出栈,获得栈头这些功能都要有。因为题里还涉及到求最大公约数,再手写一个gcd。代码放在下面了,非常简单,很好理解。如果有不懂的可以评论区问我。希望大家多多支持,后续我还会更新其他竞赛题目的题解。非常感谢


#include<iostream>
using namespace std;
const int N = 1e6 + 20;
#include<stdio.h>
typedef long long int LL;  
LL tt = -1;
LL st[N]; //用来模拟栈的数组
LL a[N]; //用来保存栈顶前x个数,目的是求他们的最大公约数

void push(int x){//入栈
	st[++tt] = x;
}
void pop(){ //出栈

	tt--;
}
int top(){   //获得栈头
	return st[tt];
}
int size() //获得栈内元素个数
{
	return tt;
}
LL gcd(LL a, LL b){  //gcd求最大公约数
	return b ? gcd(b, a%b) : a;
}
int main(){

	LL n;
	scanf("%d",&n);
	while (n--){
		LL op;
			scanf("%d",&op);
		if (op == 1){
			int x;
			cin >> x;
			push(x);
		}
		else if (op == 2){
			pop();
		}
		else if (op == 3){
			printf("%d\n",top());
		}
		else if (op == 4){
			LL x;
			cin >> x;
			LL ans = 0;
			for (int i = 0; i<x; i++){
				a[ans++] = top();
				pop();
			}
			LL d = 0;
			for (int i = 0; i<ans; i++){
				 d = gcd(d, a[i]);    //因为0与所有的数求最大公约数,最大公约数都是另一个数
                if(d==1)     //这里需要注意,当d为1的时候,所有数和1的最大公约数就是1了,直接跳出循环。(如果不加此步骤会TLE)
                    break;
			}
			for (int i = 0; i<ans; i++)
				push(d); //再讲求得的最大公约数入栈
		}
	}

	return 0;
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值