数据结构实验(四)栈与队列的操作与应用
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;
}