寒假第三次作业

一、Priority Queue

直接用priority queue实现

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

priority_queue<int> q;
int main(){
	string a;
	int b;
	
	while(1){
		cin>>a;
		if(a=="insert"){
			cin>>b;
			q.push(b);
		}
		else if (a=="extract"){
			int t=q.top();
			cout<<t<<endl;
			q.pop();
		}
		else if(a=="end")break;
	}
} 

二、ST表

直接使用st表

 #include <bits/stdc++.h>
 using namespace std; 
 const int N = 1e5+5,T = log2(N)+1;
 int st[N][T],log_2[N];


int main(){
	int n,m;
	scanf("%d %d", &n, &m);
	log_2[1]=0;
	for(int i=2;i<=n;i++){
		log_2[i]=log_2[i/2]+1;
	}
	for(int i=1;i<=n;i++){
		scanf("%d", &st[i][0]);
	}
	for(int j=1;j<=log_2[n];j++){
		for(int i=1;i+(1<<j)-1<=n;i++){
			st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}
	int l,r;
	for(int i=1;i<=m;i++){
		scanf("%d %d", &l, &r);
		int s=log_2[r-l+1]; 
		printf("%d\n", max(st[l][s], st[r - (1 << s) + 1][s]));
	}
	return 0;
} 

三、合并果子

使用小根堆,先添加所有数据,在每次删除两个最小的,添加这两者的和,重复n-1次

 #include <bits/stdc++.h>
 using namespace std; 
 
 const int N = 1e4+5;
 int A[N];
 struct Compare {
    bool operator()(int a, int b) {
        return a > b;
    }
};
 int main (){
 	int n;
 	cin>>n;
 	for(int i = 1 ;i<=n;i++){
 		cin>>A[i];
	}
	priority_queue<int, vector<int>, Compare> c;
 	for(int i = 1 ;i<=n;i++){
 		c.push(A[i]);
	}
	int m1,m2;
	long long count = 0;
	for(int i = 1 ;i<n;i++){
		m1=c.top();
		c.pop();
		m2=c.top();
		c.pop();
		c.push(m1+m2);
		count+=(m1+m2);
	}
	cout<<count<<endl;
 }

四、约瑟夫问题

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

int main() {
    int n, m;
    cin >> n >> m;
    list<int> l;
    for (int i = 1; i <= n; i++) {
        l.push_back(i); 
    }
    int count = 0; 
    auto it = l.begin(); 
    while (!l.empty()) {
        count++;
        if (count == m) {
            cout << *it << " ";
            it = l.erase(it);
            count = 0;
            if (l.empty()) break;
            if (it == l.end()) {
                it = l.begin();
            }
        } else {
            it++;
            if (it == l.end()) {
                it = l.begin();
            }
        }
    }
    return 0;
}

五、仰望奶牛

使用栈,找到阶段性最高点,再让入栈元素一个个出栈

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int H[N];

int main(){
	int n;
	cin>>n;
	stack<int> st;
	vector<int> result(n+1, 0);
	for (int i = 1; i <= n; i++) {
        cin >> H[i];
    }
    for (int i = n ; i >= 1; i--){
    	while (!st.empty() && H[st.top()] <= H[i]) {
            st.pop();
        }
        if(!st.empty()){
        	result[i] = st.top();
		}
		st.push(i);
	}
	for (int i = 1; i <= n; i++) {
        cout << result[i] << endl;
    }
    return 0;
}

六、国旗

可以观察到,输入元素的起始点是递增的

使用st表,找到一定距离内,一个人最多跑到哪(下一个人的起点),再检测是否符合自己的奔袭区间

 

#include <bits/stdc++.h>

using namespace std;
using namespace std;
int n, m, res[200005];
struct soldier {
	int id, l, r;
} s[420005];
int cmp(soldier a, soldier b)
{
	return a.l < b.l; 
}

int go[420005][20];

void pre()
{
	for(int i = 1, p = i; i <= 2 * n; i++) {
		while(p <= 2 * n && s[p].l <= s[i].r)
			p++;
		int pos = p - 1;
		go[i][0] = pos;
	}
	for(int i = 1; i < 20; i++) {
		for(int j = 1; j <= 2 * n; j++) {
			go[j][i] = go[go[j][i - 1]][i - 1];
		}
	}
}
void search(int k)
{
	int lmt = s[k].l + m, ans = 1, p = k;
	for(int i = 19; i >= 0; i--) {
		if(go[k][i] != 0 && s[go[k][i]].r < lmt) {
			ans += (1 << i);
			k = go[k][i];
		}
	}
	res[s[p].id] = ans + 1;
}
int main()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
		cin >> s[i].l >> s[i].r;
		if(s[i].r < s[i].l)
			s[i].r += m;
		s[i].id = i;
	}
	sort(s + 1, s + 1 + n, cmp);
	for(int i = 1; i <= n; i++) {
		s[i + n] = s[i];
		s[i + n].l = s[i].l + m;
		s[i + n].r = s[i].r + m;
	}
	pre();
	for(int i = 1; i <= n; i++)
		search(i);
	for(int i = 1; i <= n; i++)
		cout << res[i] << " ";
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值