啃了两道以前没写的每周训练的题和数据结构的学习
P1750出栈序列
一开始没读懂题目,以为是把所有的区间进行一个排序从小到大输出,不过题目确实难懂,后来看题解才弄清楚是把元素按顺序压入一个固定大小的栈,可以随时弹出栈顶元素,但是要保证弹出的数字序列靠左边的数字要尽可能小,因为随时弹出栈顶元素就导致了你的序列有很多很多种顺序的组成可能,最后的解法是找目前能放入栈的元素里的最小值,如果该最小值小于栈顶元素,则全部压入栈让最小值作为栈顶,再弹出栈顶,如果该最小值不小于栈顶元素,则弹出栈顶元素直到栈空或者最小值小于当前元素,再弹出栈顶,接着循环上述操作,可以保证每次弹出的值都是最小的正确的解。
#include<bits/stdc++.h>
using namespace std;
int a[10009];
int main(){
int n,m;
scanf("%d %d",&n,&m);
stack<int>sta;
int k=0,pos=0,cnt=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
while(cnt+sta.size()<n){
int minn=2e9;
for(int i=k;i<k+m-sta.size()&&i<n;i++){
if(a[i]<minn){
minn=a[i];
pos=i;
}
}
if(sta.empty()||minn<sta.top()){
for(int i=k;i<=pos;i++){
sta.push(a[i]);
}
k=pos+1;
}
printf("%d ",sta.top());
sta.pop();
cnt++;
}
while(!sta.empty()){
printf("%d ",sta.top());
sta.pop();
}
return 0;
}
P1645 序列
一看到这个题就想到了以前做过的区间排序,这个题要用贪心的思路,所以怎么贪才是关键,想了一会想不出来了只能去题解寻找帮助,看到了dalao的题解受了启发,定义了一个vis数组表示数字是否取到,再对所有区间按照右区间的大小进行排序,从右端点开始取数字
#include<bits/stdc++.h>
using namespace std;
struct nb{
int left;
int right;
int num;
};
bool cmp(nb a,nb b){
return a.right<b.right;
}
bool vis[1009];
int main(){
int n,ans=0;
scanf("%d",&n);
nb a[1009];
for(int i=1;i<=n;i++){
scanf("%d %d %d",&a[i].left,&a[i].right,&a[i].num);
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
int cnt=0;
for(int j=a[i].left;j<=a[i].right;j++){
if(vis[j]){
cnt++;
}
}
if(cnt<a[i].num){
for(int j=a[i].right;j>=a[i].left;j--){
if(!vis[j]){
cnt++;
ans++;
vis[j]=true;
if(cnt==a[i].num)break;
}
}
}
}
printf("%d",ans);
return 0;
}
数据结构学习
在存储一大波数时,我们通常用的是数组,但是有时候数组不太灵活,比如我们要在数组中间插入一个数,那么我们要把插入的那个数后面的数都往后面移一位,然后在中间空缺的那个位置填入该数,就会十分麻烦与繁琐,所以引入了链表这一概念。
下面是链表的构建和输出
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
int main(){
struct node *head,*p,*q,*t;
int i,n,a;
scanf("%d",&n);
head=NULL;
for(i=1;i<=n;i++){
scanf("%d",&a);
p=(struct node *)malloc(sizeof(struct node));
p->data=a;
p->next=NULL;
if(head==NULL)head=p;
else q->next=p;
q=p;
}
//输出部分
t=head;
while(t!=NULL){
printf("%d ",t->data);
t=t->next;
}
return 0;
}
这样写没有错误,但是没有进行free操作释放空间,数据如果特别大可能会产生错误
下面是对链表的插入操作,将一个数插在大于自己的数的前面(升序数),同时加上了内存释放的操作。
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
int main(){
struct node *head,*p,*q,*t;
int i,n,a;
scanf("%d",&n);
head=NULL;
for(i=1;i<=n;i++){
scanf("%d",&a);
p=(struct node *)malloc(sizeof(struct node));
p->data=a;
p->next=NULL;
if(head==NULL)head=p;
else q->next=p;
q=p;
}
scanf("%d",&a);
t=head;
//插入部分
while(t!=NULL){
if(t->next==NULL||t->next->data>a){
p=(struct node *)malloc(sizeof(struct node));//存放加入的节点
p->data=a;
p->next=t->next;
t->next=p;
break;
}
t=t->next;
}
//输出部分
t=head;
while(t!=NULL){
printf("%d ",t->data);
t=t->next;
}
// 释放内存部分
t = head;
while(t != NULL){
p = t;
t = t->next;
free(p); // 释放每个节点的内存
}
return 0;
}
水一篇先