- chenshixian 的博客
陈室先的总结7.18day10
- @ 2024-7-18 19:22:37
题目传送门🛫
T1 排队
思路
我们可以用双向队列来模拟
代码
#include<bits/stdc++.h>
using namespace std;
int a[1000010],h=100000,t=99999,w=1,s,c;
int main(){
freopen("pd.in","r",stdin);
freopen("pd.out","w",stdout);
cin>>s;
for(int i=1;i<=s;i++){
char x,y;
cin>>x>>y;
if(x=='A'&&y=='L'){a[--h]=w,w++;}
if(x=='A'&&y=='R'){a[++t]=w,w++;}
if(x=='D'&&y=='L'){
cin>>c;
h+=c;
}
if(x=='D'&&y=='R'){
cin>>c;
t-=c;
}
// for(int j=h;j<=t;j++)cout<<a[j]<<' ';
}
for(int j=h;j<=t;j++)cout<<a[j]<<"\n";
}
T2 插入删除
错的点
1.用的是单链表,而且写的复杂,这题本来要用双链表的,以后要加强熟练度
思路
双链表模板
代码
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
unordered_map<int,int> m;
int l[N],r[N],e[N],idx,n,q;
void init() {
r[0]=1;
l[1]=0;
idx=2;
}
void add(int k, int x) {
m[x]=idx;
e[idx]=x;
l[idx]=k;
r[idx]=r[k];
l[r[k]]=idx;
r[k]=idx++;
}
void remove(int k) {
r[l[k]]=r[k];
l[r[k]]=l[k];
}
int main(){
freopen("insdel.in","r",stdin);
freopen("insdel.out","w",stdout);
init();
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
if(i==1)add(0,x);
else add(i,x);
}
cin>>q;
while(q--){
int x,y,z;
cin>>x;
if(x==1){
cin>>y>>z;
add(m[y],z);
}
else{
cin>>y;
remove(m[y]);
}
cout<<"\n";
}
for(int i=r[0];e[i]!=0;i=r[i])cout<<e[i]<<" ";
}
T3 拍照
错的点
比赛时骗的分,而再写时最小值设制极大值时设小了
思路
可以用二分来做,用两个变量维护区间,如果可以就l++直到不行为止,如果不可以j++,这里判断是还要加哈希来标记,前面记得排序
代码
#include<bits/stdc++.h>
using namespace std;
unordered_map<long long,long long>m,j;
long long n,an=100000;
struct P{
long long w,p;
}a[50010];
bool cmp(P a,P b){
return a.w<b.w;
}
int main(){
freopen("photo.in","r",stdin);
freopen("photo.out","w",stdout);
long long s=0,h=1000000010,l=1,r=1;
cin>>n;
for(long long i=1;i<=n;i++){
cin>>a[i].w>>a[i].p;
if(j[a[i].p]==0)s++;
j[a[i].p]++;
}
sort(a+1,a+1+n,cmp);
while(l<=n&&r<=n){
if(m[a[r].p]==0)s--;
m[a[r].p]++;
if(s!=0)r++;
if(s==0){
h=min(h,a[r].w-a[l].w);
if(m[a[l].p]==1)s++,l++;
else l++;
m[a[l-1].p]--;
}
}
cout<<h;
}
T4 小马要做最棒的牛
错的点
十年OI一场空,不开longlong见祖宗
思路
用表达式求值的思路,遇到左括号压入,右括号算分
代码
#include<bits/stdc++.h>
using namespace std;
long long f[100010],h=-1,e=12345678910;
int main(){
freopen("horse.in","r",stdin);
freopen("horse.out","w",stdout);
long long n;
cin>>n;
for(long long i=1;i<=n;i++){
long long x;
cin>>x;
if(x==0)f[++h]=-1;
if(x==1){
if(f[h]>-1){
long long j=0;
while(f[h]!=-1){
j%=e;
j=(j+f[h])%e;
h--;
}
h--;
f[++h]=((j%e)*2)%e;
}
else{
h--;
f[++h]=1;
}
}
cout<<"\n";
}
long long s=0;
for(long long i=0;i<=h;i++)s=(s+f[i])%e;
cout<<s%e;
}
T5 小田在努力切割木板
错的点
纯暴力,以后要多思考
思路
这道题我们可以反着想,然后又会发现每次两个最小的和,合会最小,所以可以用堆
代码
#include<bits/stdc++.h>
using namespace std;
priority_queue<long long,vector<long long>,greater<long long>>k;
int main(){
freopen("qg.in","r",stdin);
freopen("qg.out","w",stdout);
long long n,z=0,h=0;
cin>>n;
for(long long i=1;i<=n;i++){
int x;
cin>>x;
k.push(x);
}
for(long long i=1;i<n;i++){
h=k.top();
k.pop();
h+=k.top();
k.pop();
z+=h;
k.push(h);
}
cout<<z;
}