列表

详情


NC15409. 神奇的数据结构栈

描述

大家刚刚接触数据结构,发现这是个非常神奇的东东。如果没接触也没有关系,给大家介绍一下。栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。

1.进栈(PUSH)算法

①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);

②置TOP=TOP+1(栈指针加1,指向进栈地址);

③S(TOP)=X,结束(X为新进栈的元素);

2.出栈(POP)算法

①若TOP≤0,则给出下溢信息,作出错处理(出栈前先检查是否已为空栈, 空则下溢;不空则作②);

②X=S(TOP),(出栈后的元素赋给X):

③TOP=TOP-1,结束(栈指针减1,指向栈顶)。
比如现在有序列1,2,3入栈,那么可能出栈的序列有:1,2,3;1,3,2;3,2,1;2,1,3;2,3,1;共5种;
那么锐神提出一个问题就来了:如果有n个元素进栈,那么有多少种方式出栈呢?帮帮锐神吧,送你一个气球作为奖励。嘿嘿嘿。。。。

输入描述

第一行一个数T,表示有T组数据。
对于每组数据,
每行一个整数N

输出描述

每一组数据输出一行,满足条件的出栈序列数量。

示例1

输入:

3
1
2
3

输出:

Case #1: 1
Case #2: 2
Case #3: 5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java(javac 1.8) 解法, 执行用时: 55ms, 内存消耗: 14508K, 提交时间: 2020-10-13 13:44:28

import java.io.*;
import java.util.*;
public class Main {
	private static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static final int N=(int)2e5+10;
	static final int mod=998244353;
	static int T,n,m,k,x,y,z;
	static long f[]=new long[N];
	static long ksm(long x,long y) {
		long rs=1;
		while(y!=0) {
			if(y%2==1)rs=rs*x%mod;
			y>>=1;
			x=x*x%mod;
		}
		return rs;
	}
	static long C(int x,int y) {
		return f[x]*ksm(f[y]*f[x-y]%mod,mod-2)%mod;
	}
	public static void main(String[] args) throws IOException {
		Scanner rd = new Scanner(System.in);
		f[0]=1;
		for(int i=1;i<=200000;i++)f[i]=f[i-1]*i%mod;
		k=rd.nextInt();
		while(k-->0) {
			n=rd.nextInt();
			System.out.println("Case #"+(++m)+": "+C(n*2,n)*ksm(n+1,mod-2)%mod);
		}
        rd.close();
	}
}

pypy3 解法, 执行用时: 87ms, 内存消耗: 25392K, 提交时间: 2023-02-08 10:37:04

mod = 998244353  # 题目没有说要mod,简直是天坑
top = 200004     # 题目说范围在10**5, 开100004的数组却越界,又是个天坑
fac = [1] * (top + 1)
fac[0] = fac[1] = 1
for i in range(2, top + 1):
    fac[i] = fac[i - 1] * i % mod
inv = [0] * (top + 1)
inv[-1] = pow(fac[-1], mod - 2, mod)
for i in range(top - 1, -1, -1):
    inv[i] = inv[i + 1] * (i + 1) % mod
    
def perm(n, m):
    return (fac[n] * inv[n - m]) % mod

def comb(n, m):
    return (perm(n, m) * inv[m]) % mod

for i in range(int(input())):
    n=int(input())
    print(f'Case #{i+1}: {(comb(2*n,n)-comb(2*n,n-1)) % mod}')

C++(clang++11) 解法, 执行用时: 34ms, 内存消耗: 3460K, 提交时间: 2021-08-22 20:18:32

#include<cstdio>
typedef long long ll;
const int P=998244353;
ll fact[200005],inv[200005];
inline ll qpow(ll x,ll y){
	ll ans=1;
	for(;y;y>>=1){
		if(y&1) ans=ans*x%P;
		x=x*x%P;
	}
	return ans;
}
inline ll C(int a,int b){
	return fact[a]*inv[b]%P*inv[a-b]%P;
}
int main(){
	fact[0]=inv[0]=1;
	for(int i=1;i<=200000;i++){
		fact[i]=fact[i-1]*i%P;
		inv[i]=qpow(fact[i],P-2);
	}
	int t,n;
	scanf("%d",&t);
	for(int i=1;i<=t;i++){
		scanf("%d",&n);
		printf("Case #%d: %lld\n",i,(C(2*n,n)-C(2*n,n-1)+P)%P);
	}
	return 0;
}

Python3 解法, 执行用时: 308ms, 内存消耗: 20468K, 提交时间: 2023-02-08 10:34:49

mod = 998244353
top = 200004
fac = [1] * (top + 1)
fac[0] = fac[1] = 1
for i in range(2, top + 1):
    fac[i] = fac[i - 1] * i % mod
inv = [0] * (top + 1)
inv[-1] = pow(fac[-1], mod - 2, mod)
for i in range(top - 1, -1, -1):
    inv[i] = inv[i + 1] * (i + 1) % mod
    
def perm(n, m):
    return (fac[n] * inv[n - m]) % mod

def comb(n, m):
    return (perm(n, m) * inv[m]) % mod

for i in range(int(input())):
    n=int(input())
    print(f'Case #{i+1}: {(comb(2*n,n)-comb(2*n,n-1)) % mod}')

上一题