题目1
代码
#include<iostream>
#include<queue>
#include<string>
using namespace std;
int main()
{priority_queue<int> s;string str;int a;str="0";while(str!="end"){cin>>str;if(str=="insert"){cin>>a;s.push(a);}else if(str=="extract"){cout<<s.top()<<endl;s.pop();}}}
解题思路
1.创建一个优先队列s,用于存储整数。
2.使用一个字符串str作为输入的控制变量,当str不等于"end"时,程序继续执行。
3.如果str等于"insert",则从输入中读取一个整数a,并将其插入到优先队列s中。
4.如果str等于"extract",则输出优先队列s的顶部元素(即最大元素),并将该元素从队列中移除。
题目2
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+5;
const int maxm=22; //∵log(2e6)<22
int a[maxn];
int f[maxn][maxm]; //f[i][j]表示从i位起的2^j个数中的最大数int main() {int n,m,x,y;scanf("%d%d",&n,&m);for(int i=1; i<=n; i++) {scanf("%d",&a[i]); //数组a的下标从1开始f[i][0]=a[i]; //f[i][0]表示[i,i]中的最大值,只能是a[i],故f[i][0]=a[i]}for(int j=1; j<=log2(n); j++)for(int i=1; i+(1<<j)-1<=n; i++) //注意i的右端点为i+(1<<j)-1,不能越界f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); //预处理for(int i=1; i<=m; i++) { //查询scanf("%d%d",&x,&y);int k=log2(y-x+1);printf("%d\n",max(f[x][k],f[y-(1<<k)+1][k]));}return 0;
}
解题思路
创建一个set容器s,用于存储整数。
使用一个字符串str作为输入的控制变量,当str不等于"end"时,程序继续执行。
如果str等于"insert",则从输入中读取一个整数a,并将其插入到集合s中。由于set会自动排序,所以插入后集合仍然是有序的。
如果str等于"extract",则输出集合s的第一个元素(即最小元素),并将该元素从集合中移除。
题目3
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{priority_queue<int,vector<int>,greater<int> > pque;int n,i,x,a,b,sum=0;cin>>n;for(i=0; i<n; i++){cin>>x;pque.push(x);}if(pque.size()==1){sum=pque.top();}while(pque.size()>1){a=pque.top();pque.pop();b=pque.top();pque.pop();x=a+b;pque.push(x);sum+=x;}cout<<sum<<endl;return 0;
}
解题思路
创建一个优先队列pq,用于存储整数。
使用一个字符串str作为输入的控制变量,当str不等于"end"时,程序继续执行。
如果str等于"insert",则从输入中读取一个整数a,并将其插入到优先队列pq中。
如果str等于"extract",则输出优先队列pq的顶部元素(即最大元素),并将该元素从队列中移除。
题目4
代码
#include<iostream>
using namespace std;
int a[100]={0};
int main()
{int m,n,i=1,sum=0,k=0;//sum是出局人数cin>>n>>m;while(n!=sum)//当出局人数!=n 进入{if(i>n)//当i>n的时候从1重新报数i=1;if(a[i]==0)//只有当元素值为0进入 否则直接++{k++;//k计数器++if(k==m){sum++;k=0;//k从0开始报数a[i]=1;//元素值变1 表示出局 往后不再报数cout<<i<<" ";}}i++;}return 0;
}
解题思路
初始化一个整数数组a,用于标记每个战士是否已经出局,初始状态下所有战士都未出局。
读取输入的战士数量n和报数上限m。
使用一个变量i从1开始循环,模拟报数过程。
如果当前战士未出局(即a[i]为0),则计数器k加1。
如果计数器k达到报数上限m,则该战士出局(将a[i]设置为1),计数器k重置为0,并输出该战士的编号。
循环结束条件为出局人数sum等于战士总数n。
题目5
代码
#include <cstdio>
#include <iostream>
using namespace std;
int n,h[100001],b[100001],stack[100001],top=1;
int main()
{scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d",&h[i]);stack[1]=1;for (int i=2;i<=n;i++){while (h[i]>h[stack[top]] && top>=1) {b[stack[top]]=i;top--;}top++;stack[top]=i;}while (top>=1)b[stack[top--]]=0;for (int i=1;i<=n;i++)printf("%d\n",b[i]);return 0;
}
解题思路
读取输入的整数数量n。
初始化一个整数数组h,用于存储输入的整数。
初始化一个整数数组b,用于存储每个元素的下一个更大元素。
初始化一个栈stack,用于辅助构建单调栈。
将第一个元素的索引1入栈。
从第二个元素开始遍历数组h:
如果当前元素大于栈顶元素对应的数组值,则栈顶元素出栈,并更新出栈元素的下一个更大元素为当前 元素。
重复上述步骤,直到栈为空或者栈顶元素对应的数组值大于当前元素。
将当前元素的索引入栈。
遍历结束后,栈中可能还剩下一些元素,这些元素没有下一个更大元素,将它们的下一个更大元素设置为0。
输出数组b中的每个元素。
题目6
代码
#include<bits/stdc++.h>
using namespace std;int n, m;
int n2;
int go[400005][20];
int res[400005];struct person{ int id;//id:战士的编号int left, right;//战士的左右区间//按左边排序 bool operator < (const person b) const{return left < b.left;}
}w[400005];void fun1() { int next = 1;for(int i = 1;i <= n2; i++) { //每个区间的下一个是右端点最大的那个区间while(next <= n2 && w[next].left <= w[i].right) {next++;}go[i][0] = next - 1; //区间i的下一个最优区间}//倍增for(int i = 1; (1 << i) <= n; i++) {//1 << i即将1转换为二进制数后,左移i位for(int s = 1; s <= n2; s++) {go[s][i] = go[go[s][i - 1]][i - 1];//go[s][i]表示从第s个区间出发,走2^i个最优区间后到达的区间 } }
}void fun2(int x) { int len = w[x].left + m;//从第x个战士出发,移动一圈 int cur = x, ans = 1;for(int i = log2(n); i >= 0; i--) { int pos = go[cur][i];if(pos && w[pos].right < len) {ans += 1 << i; //累加跳过的区cur = pos; }}res[w[x].id] = ans + 1;
}int main()
{cin >> n >> m;for(int i = 1; i <= n; i++) {w[i].id = i; cin >> w[i].left >> w[i].right;if(w[i].right < w[i].left) w[i].right += m;}sort(w+1, w+n+1); n2 = n;//n2就是复制后再相接 for(int i = 1; i <= n; i++) { n2++; w[n2].id = w[i].id; w[n2].left = w[i].left + m;w[n2].right = w[i].right + m;}fun1();for(int i = 1;i <= n; i++) {fun2(i); }for(int i = 1; i <= n; i++) {cout << res[i] << " ";}return 0;
}
解题思路
读取输入的战士数量n和移动距离m。
初始化一个结构体数组w,用于存储每个战士的信息,包括编号、左端点和右端点。
对结构体数组w按照左端点进行排序。
复制结构体数组w,并将复制后的数组接在原数组后面,形成一个长度为2n的新数组,用于处理循环的情况。
初始化一个二维数组go,用于存储每个区间的下一个最优区间。
初始化一个数组res,用于存储每个战士的最终答案。
调用fun1函数,预处理出每个区间的下一个最优区间。
遍历每个战士,调用fun2函数,计算每个战士能够移动到的最远距离。
输出数组res中的每个元素,即每个战士的最终答案。