补题*总结题21/8/24
最近水题有点多,就不记录了
水题
点击展开
- 水1.D - Husam's Bug
- 水2.F - Certifications
- -(本来是没看懂题意,尝试一下题意是什么,暴力了一下,就过了........)
- 大水3. G - In the Chairman's office
}
}
H - Give Me This Pizza
Gym - 101343H
题意:
对于数组a[n]的所有位置,找到a[i]右边第一个比他大的数max,并把a[i]改成max
思路1:ai才不到50 从后往前暴力即可 存每个数最后出现的位置
代码1:
#include <bits/stdc++.h>
using namespace std;
int vis[55];//记录某数字最后相对最前出先的位置
int q[100005];//原数据
int ans[100005];//修改后的数据
int main()
{
int n;
cin>>n;
for(int i = 1; i <= n; i++) cin>>q[i];
for(int i = 1; i <= 50; i++)
vis[i] = 1000005;
for(int i = n; i >= 1; i--)
{
vis[q[i]] = i;//记录某数字最后相对最前出先的位置
int mini_max = -1;//记录i时,较大值
int t=1000005;//记录i时,距离i最近的较大值位置
for(int j = q[i] + 1; j <= 50; j++)//查找离q[i]最近的较大值
{
if(vis[j] < t)//如果数j的位置更近
{
t= vis[j];//更新较大值位置
mini_max = j;//更新较大值
}
}
ans[i] = mini_max;//把较大值作为ans[i],如果没有较大值则为-1
}
for(int i = 1; i <= n; i++)
{
if(i != n) printf("%d ", ans[i]);
else printf("%d\n", ans[i]);
}
return 0;
}
思路2:(未看懂)
转自:链接
·· 首先我们用s数组来从尾到头来记录第一个大于 该第i个元素的 下标
·· 进行初始化,最尾一个元素必定为-1,所以赋值s[n]=n+1,a[n+1]=-1;
·· 用 t 来描述它后一位元素 如果大于那么a[i]的答案为a[t]
所以用s[i]=t来记录;
代码2:
#include<iostream>
#include<algorithm>
#include<map>
#include<string>
#include<cstring>
using namespace std;
int a[100005];
int s[100005];
int main(){
int n; cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i];
s[n] = n + 1;//初始化
a[n + 1] = -1;
for (int i = n - 1; i >= 1; i--) {
int t = i + 1;//答案下标 ,以后一位来找到 “根“
while (t <= n && a[i] >= a[t])t = s[t];//找到第一个大于a[i]的值
s[i] = t;
}
for (int i = 1; i <= n; i++)
cout << a[s[i]] << " ";
return 0;
}