数据结构实验(四)栈与队列的操作与应用

6-1 用顺序栈实现将非负的十进制数转换为指定的进制数

这个其实就是每次把余数放进栈中就好了

int DecimalConvert(SqStack *s, int dec, int scale){
    InitSqStack( s );
    while( dec ){
        SqStackPush( s , dec % scale );
        dec /= scale;
    }
    return 1;
}

6-2 用链栈实现将非负的十进制数转换为指定的进制数

与上一题相同,不同的是栈的事项方式不同了

int DecimalConvert(LinkStack s, int dec, int scale){
    InitLinkStack( s );
    while(  dec ){
        LinkStackPush( s , dec % scale );
        dec /= scale;
    }
    return 1;
}

6-3 带头结点的链队列的基本操作

这里就是两个很基础的操作,参考课本就好了

Status QueueInsert(LinkQueue *Q, ElemType e)
{
	LinkList p;
	p = (LinkList)malloc(sizeof(LinkList));
	if (p == NULL)
	{
		return ERROR;
	}
	p->data = e;
	p->next = NULL;
	Q->rear->next = p;
	Q->rear = p;
	return OK;
}
Status QueueDelete(LinkQueue *Q, ElemType *e)
{
	LNode *p;
	p = Q->front->next;
	if (Q->front == Q->rear)
	{
		*e = -1;
		return ERROR;
	}
	Q->front->next = p->next;
	*e = p->data;
	free(p);
	return OK;
}

6-4 括号匹配判断

括号匹配也是一个非常经典的做法,遇到左括号就入栈,遇到右括号就和栈顶比较时候匹配,匹配出栈,否则括号序列不合法

int match( char * exp ){
    char stk[N] , top = 0;
    for( int i = 0 ; i < strlen( exp ) ; i ++){
        if( exp[i] == '(' ) stk[ ++ top ] = '(';
        if( exp[i] == '[' ) stk[ ++ top ] = '[';
        if( exp[i] == '{' ) stk[ ++ top ] = '{';
        if( exp[i] == ')' ){
            if( top > 0 && stk[top] == '(' ) top --;
            else return 0;
        }
        if( exp[i] == ']' ){
            if( top > 0 && stk[top] == '[' ) top --;
            else return 0;
        }
        if( exp[i] == '}' ){
            if( top > 0 && stk[top] == '{' ) top --;
            else return 0;
        }
    } 
    return top == 0;
}

7-1 表达式求值

python 很简单

a = input()
try:
    b = int(eval( a ))
    print(b)
except:
    print("ILLEGAL")

7-2 括号匹配检测

括号匹配也是一个非常经典的做法,遇到左括号就入栈,遇到右括号就和栈顶比较时候匹配,匹配出栈,否则括号序列不合法

#include<bits/stdc++.h>

using namespace std;

int main(){
    int cnt = 0;
    string s;
    cin >> s;
    stack<char> stk;
    for( auto it : s )
        switch (it) {
            case '(':
            case '{':
            case '[':
                stk.push(it);
                break;
            case ')':
                if( stk.size() && stk.top() == '(' ) cnt ++ , stk.pop();
                else cout << "0\n" , exit(0);
                break;
            case ']':
                if( stk.size() && stk.top() == '[' ) cnt ++ , stk.pop();
                else cout << "0\n" , exit(0);
                break;
            case '}':
                if( stk.size() && stk.top() == '{' ) cnt ++ , stk.pop();
                else cout << "0\n" , exit(0);
                break;
        }
    if( stk.empty() )cout << cnt << "\n";
    else cout << "0\n";
    return 0;
}

7-3 银行排队问题之单队列多窗口服务

每次遍历一下所有的队列找到最短的队伍,或者是空队,如果有多个不用排队的队伍,记得选择编号最小的一个

#include<bits/stdc++.h>
using namespace std;

int read(){...}

int main(){
    int n = read();
    vector< pair<int,int> > v(n);
    for( auto & [ t , p ] : v )
        t = read() , p = min( 60 , read() );
    int k = read();
    vector< stack<int> > stk(k);
    int waitSum = 0 , waitMax = 0 , endTime = 0;
    for( auto [ t , p ] : v ){
        int startTme = INT_MAX;
        for( auto &it : stk ){
            if( it.empty() || it.top() <= t ) {
                startTme = -1 , it.push(t+p);
                break;
            }
            else startTme =  min( startTme , it.top() );
        }
        if( startTme == -1 ) continue;
        for( auto &  it : stk ){
            if( it.top() == startTme ){
                it.push( startTme + p );
                int wait = startTme - t;
                waitSum += wait , waitMax = max( waitMax , wait );
                break;
            }
        }
    }
    printf("%.1lf " , 1.0 * waitSum / n );
    cout << waitMax << " ";
    for( auto it : stk )
        if( !it.empty() ) endTime = max( endTime , it.top() );
    cout << endTime << "\n";
    for( auto it : stk )
        cout << it.size() << ( it == stk.back() ? "\n" : " " );

}

7-4 列车调度

这里需要多个队列,但是实际上我们并不需要真的委维护队列,而是维护一下队列的最后一个数就好了。

首先判断,如果没有队列,或者所有的队尾都比当前小,那么就需要新开一个队列。但是如果有有多个队尾比当前大,那么就需要贪心的选择出最小的队列,然后更新该队列的队尾。

因为涉及的反复的修改,可以用 set 来降低复杂度

#include<bits/stdc++.h>

using namespace std;

int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

int32_t main() {
    set<int> q;
    for( int n = read() , x ; n ; n -- ){
        x = read();
        if( q.size() == 0 || *q.rbegin() < x )  q.insert(x);
        else q.erase( q.upper_bound(x) ) , q.insert(x);
    }
    cout << q.size() << "\n";
}

7-5 迷宫探路

很常规的 bfs 模板

#include<bits/stdc++.h>

using namespace std;

int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

const int N = 105;
const int dx[] = { 1 , -1 , 0 , 0 } , dy[] = {0 , 0 , -1 , 1 };
int vis[N][N] , f[N][N];
void solve(){
    int n = read() , m = read();
    fill( vis[0] , vis[0] + N * N , 0 );
    fill( f[0] , f[0] + N*N , INT_MAX );
    for( int t = read() , x , y ; t ; t -- )
        x = read() , y = read() , vis[x][y] = 1;
    int sx = read() , sy = read() , ex = read() , ey = read();
    queue< pair<int,int> > q;
    vis[sx][sy] = 1 , f[sx][sy] = 0 , q.push( {sx,sy} );
    while( !q.empty() ){
        auto [x,y] = q.front();
        q.pop();
        for( int i = 0 , fx , fy ; i < 4 ; i ++ ){
            fx = x + dx[i] , fy = y + dy[i];
            if( fx < 0 || fx >= n || fy < 0 || fy >= m || vis[fx][fy] ) continue;
            if( f[fx][fy] > f[x][y] + 1 ){
                f[fx][fy] = f[x][y] + 1;
                q.push( { fx ,fy } );
            }
        }
    }
    if( f[ex][ey] == INT_MAX ) cout << "Not arrive\n";
    else cout << f[ex][ey] << "\n";
    return;
}

int32_t main() {
    for( int T = read() ; T ; T -- )
        solve();
    return 0;
}
posted @ 2022-10-13 14:18  PHarr  阅读(237)  评论(0编辑  收藏  举报