周测题解1

A

栈的基本使用

【模板】栈 - 洛谷

#include <bits/stdc++.h>//喜欢万用❤
using namespace std;
using ll = unsigned long long;//应该开long long,2的64次方

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    ll T, n;
    for (cin >> T;T > 0; --T) {
        stack<ll> s;//定义,重定义
        for (cin >> n; n; --n) {
            string st;
            cin >> st;
            if (st == "push") {
            ll x;
            cin >> x; s.push(x);
            } else if (st == "pop") {
            if (s.empty()) cout << "Empty\n";//判空,之后每次也都要判空
            else s.pop();
            } else if (st == "query") {
            if (s.empty()) cout << "Anguei!\n";
            else cout << s.top() << '\n';
            } else cout << s.size() << '\n';
		}
	}
  return 0;
}

 B

栈栈栈栈栈栈

【模板】单调栈 - 洛谷

#include<bits/stdc++.h>
using namespace std;
const int N = 3 * 1e6 + 9;
int n,a[N],f[N];
stack<int>s;
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n;
	for(int i=1;i<=n;i++) cin >> a[i];
	for(int i=n;i>=1;i--)
	{
		while(!s.empty()&&a[s.top()]<=a[i]) s.pop();//如果当前栈顶数更小,把栈顶弹出
		if (s.empty()) {
            f[i] = 0;//没有更大的,输出0
        } else {
    f[i] = s.top();
    }
		s.push(i);//压入
	}
	for(int i=1;i<=n;i++) printf("%d ",f[i]);
	return 0;
}

C

快速幂,减少复杂度

【模板】快速幂 - 洛谷

#include<bits/stdc++.h>
using namespace std;
using ll =long long;
ll a, b, p;//开ll,会比较大
ll quickpow(ll a,ll b){
	if(b==1){
		return a;
	}else if(b == 0){
		return 1;
	}else{
		ll ans=quickpow(a, b / 2) % p;//哎哎,递归,建议大家看别的题解,写点简单的,base看的比这舒服
		ll ans1=(ans % p * ans % p) % p;
		if(b % 2 == 1){
			ans1=(ans1 % p * a % p) % p;
		}
		ans1 = ans1 % p;
		return ans1;
    }
}
int main(){
    cin >> a >> b >> p;
	ll ans = quickpow(a, b);
	ans = ans % p;
	printf("%lld^%lld mod %lld=%lld", a, b, p, ans);//注意输出格式
	return 0;
}

D🤬

高精求小数幂 - 洛谷

E

并查集

【模板】并查集 - 洛谷

#include<bits/stdc++.h>
using namespace std;
const int X = 10010;
int f[X];
int n,m;

void init(){//初始化并查集,将每个元素都初始化为自己所在的集合
	for(int i = 0;i <= X - 1;i++) f[i] = i;
}

int find_f(int x){//用于查找元素所在的集合,通过递归的方式找到根节点,并将路径压缩,使得后续查找更快
	if(x != f[x]){
		return f[x] = find_f(f[x]);
	}
	return f[x];
}

void merge(int x,int y){用于合并两个集合,将其中一个集合的根节点指向另一个集合的根节点
	int fx = find_f(x), fy = find_f(y);
	if(fx != fy){
		f[fy] = fx;
	}
}

int main(){
	init();
	cin >> n>> m;
	while(m--){
		int t, x, y;
		cin >> t >> x >> y;
		switch(t){//1,2的设定在治理挺好用
			case 1:
				merge(x, y);
				break;
			case 2:
				if(find_f(x) == find_f(y)){
	            cout << "Y" << endl;
                }else{
	            cout << "N" << endl;
                }
				break;
		}
	}
	return 0;
}

F

朋友

朋友 - 洛谷

#include<bits/stdc++.h>
using namespace std;
int n,m,k,f1[10001],f2[10001],p,q;//f1是小明的朋友,f2是小红的朋友
int find(int f[],int a)//传数组
{  
    if(a==f[a]) return a;
    else f[a]=find(f,f[a]);//并查集
    return f[a];
}
int main()
{
    cin>>n>>m>>p>>q;
    for(int i=1;i<=n;i++) f1[i]=i;//初始化
    for(int i=1;i<=m;i++) f2[i]=i;
    for(int i=1;i<=p;i++)
    {
        int a,b;
        cin>>a>>b;
        f1[find(f1,a)]=find(f1,b);
    }
    for(int i=1;i<=q;i++)
    {
        int a,b;
        cin>>a>>b;
        a=-a;//变成正的
        b=-b;
        f2[find(f2,a)]=find(f2,b);
    }
    int root1=find(f1,1);//小明的根
    int root2=find(f2,1);//小红的根
    int t1,t2;
    t1=t2=0;
    for(int i=1;i<=n;i++) if(find(f1,i)==root1) t1++;//小明的朋友就+1
    for(int i=1;i<=m;i++) if(find(f2,i)==root2) t2++;//小红的朋友就+1
    printf("%d",t1<t2?t1:t2);//选朋友少
    return 0;
}

G

排序

【模板】排序 - 洛谷

不用讲这个罢

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 1e5 + 5;
ll a[N];

int main() {
    ll n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];

    sort(a, a + n);

    for (int i = 0; i < n; i++)
        cout << a[i] << " ";
    
    cout << endl;

    return 0;
}

K

【模板】堆 - 洛谷

一眼单调队列

#include <bits/stdc++.h>
using namespace std;
int n, m, x;
priority_queue <int, vector <int>, greater <int> > q;//小顶堆
int main() {
    cin >> n;
    while(n--) {
        cin >> m;
        if(m == 1) {
            cin >> x;
            q.push(x);
        } else if(m == 2)
            cout << q.top() << endl;
        else q.pop();
    }
    return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值