课堂练习
手造链队列
#include<cstdio>
typedef struct QNode{
int data;
QNode *next;
}QNode;
typedef struct{
QNode *front;
QNode *rear;
}LQ;
QNode *p;
LQ q;
void init(){
q.front=q.rear=new QNode;
q.front->next=NULL;
}
bool empty(){
return q.front==q.rear;
}
void push(int x){
p=new QNode;
p->data=x;
p->next=NULL;
q.rear->next=p;
q.rear=p;
}
bool pop(){
if(empty()) return false;
p=q.front->next;
q.front->next=p->next;
if(q.rear==p) q.rear=q.front;
return true;
delete p;
}
int size(){
int cnt=0;
p=q.front->next;
while(p){
cnt++;
p=p->next;
}
return cnt;
}
int main(){
init();
push(1);
push(2);
printf("len=%d\n",size());
while(!empty()){
if(!pop()) printf("error\n");
}
printf("len=%d\n",size());
return 0;
}
手造邻接表
#include<cstdio>
const int Max_num=10;
typedef struct QNode{
int data;
QNode *next;
}QNode;
typedef struct{
QNode *front;
QNode *rear;
}LQ;
QNode *p;
LQ q[Max_num+7];
void init(){
for(int i=0;i<Max_num;++i){
q[i].front=q[i].rear=new QNode;
q[i].front->next=NULL;
}
}
bool empty(){
for(int i=0;i<Max_num;++i){
if(q[i].front!=q[i].rear) return false;
}
return true;
}
void push(int pos,int x){
p=new QNode;
p->data=x;
p->next=NULL;
q[pos].rear->next=p;
q[pos].rear=p;
}
bool pop(int pos){
if(empty()) return false;
p=q[pos].front->next;
q[pos].front->next=p->next;
if(q[pos].rear==p) q[pos].rear=q[pos].front;
return true;
delete p;
}
int size(int pos){
int cnt=0;
p=q[pos].front->next;
while(p){
cnt++;
p=p->next;
}
return cnt;
}
int main(){
init();
for(int i=1;i<=Max_num;++i){
for(int j=1;j<=i;++j)
push(i%Max_num,j);
}
for(int i=0;i<Max_num;++i){
if(size(i)==0) continue;
p=q[i].front->next;
while(p){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
printf("\n\n");
for(int i=0;i<Max_num-1;i+=2)pop(i);
for(int i=0;i<Max_num;++i){
if(size(i)==0) continue;
p=q[i].front->next;
while(p){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
return 0;
}
手造栈
#include<cstdio>
using namespace std;
const int Max_num=107;
int stuckk[Max_num];
int top=0;
void push(int x){
//没判 isFull();此处写得不好
stuckk[top++]=x;
}
int pop(){
//没判 empty();此处写得不好
top--;
return stuckk[top];
}
bool empty(){
return top<=0;
}
void solve(int x,int r){//递归复杂度太高 应改为递推
push(x%r);
if(x/r==0) return;
solve(x/r,r);
return;
}
int main(){
int x,r;scanf("%d%d",&x,&r);
solve(x,r);
while(!empty())
printf("%d",pop());
return 0;
}
训练赛(部分)
其他题比较水,就不贴了。
丑数

题目。
题意:查询第n个丑数。丑数定义:质因子仅是:2、3、5的数。
思路:预处理打表。由丑数定义易发现如下规律。用优先队列遍历树+set储存即可,set主要是为了去重。但有一个注意点(此处1WA),出队时存入set,而非元素入队时。

这类可以找规律的题,一般可以先写个暴力,用来找规律或与自己程序对拍数据。像这题暴力写完发现 第1500个丑数是8e9+,O(n)都过不了,那就是稳稳的规律题了。
这题一开始我的思路是爆改素数筛,仔细一想,发现改不了,写个暴力发现素数筛复杂度也不允许。
于是老实写数据结构吧。
#include<cstdio>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;
#define ll long long
int x,tail=0;
ll a[1517],r[]={2,3,5};
set<ll> s;
void init(){ //打表
priority_queue<ll,vector<ll>,greater<ll> >q;//小的优先
q.push(1);
s.insert(1);
for(int i=1;i<=1500;++i){
ll x=q.top();q.pop();
for(int j=0;j<3;j++){
ll now=x*r[j];
if(!s.count(now)){ s.insert(now); q.push(now);}
}
}
set<ll>::iterator it=s.begin();
for(;it!=s.end()&&tail<=1500;++it){
a[++tail]=*it;
//printf("a[%d]=%lld\n",tail,a[tail]);
}
return;
}
int main(){
init();
while(~scanf("%d",&x)){
if(x==0) return 0;
printf("%lld\n",a[x]);
}
return 0;
}
括号匹配
题意:求最长匹配括号子串。
思路:用栈模拟一遍完事。这题很烦的是输入输出格式换行莫名其妙(此处3PE)。
水题,不知道为什么没人写,括号匹配各类问题还是经常遇到的。
//辣鸡输入输出
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
const int Max_num=100017;
struct S{
int id;
char x;
bool f;
}b[Max_num];
int main(){
char a[Max_num];
while(scanf("%s",a)!=EOF){
stack<S> s;
int len=strlen(a);
for(int i=0;i<len;++i){
if(s.empty()){ //栈空时直接压栈,continue
b[i].id=i;
b[i].x=a[i];
b[i].f=false;
s.push(b[i]);
continue;
}
S t=s.top();
if((t.x=='('&&a[i]==')')||(t.x=='['&&a[i]==']')){ //匹配成功,出栈,标记
s.pop();
b[t.id].f=true;
b[i].f=true;
b[i].x=a[i];
}
else { //匹配失败,压栈
b[i].id=i;
b[i].x=a[i];
b[i].f=false;
s.push(b[i]);
}
}
int maxx=0,res=0,index=0;
for(int i=0;i<len;){ //找最长标记的子串
while(i<len&&b[i].f) res++,i++;
if(res>maxx){
maxx=res;
index=i-maxx;
res=0;
}
while(i<len&&!b[i].f) i++,res=0;
}
for(int i=index;i<index+maxx;++i) printf("%c",a[i]);
printf("\n\n");
}
return 0;
}
本文介绍了大一暑期集训中关于数据结构的课堂练习,包括手造链队列、手造邻接表和手造栈。在训练赛部分,讲解了如何解决丑数问题,通过预处理和优先队列实现。此外,还讨论了括号匹配问题,使用栈进行模拟解决,指出输入输出格式需要注意的细节。

941

被折叠的 条评论
为什么被折叠?



