单调队列模板

 

#include<stdio.h>

struct Node{
	int val,index;
}que[100];

int main()
{
	int ans[100];
	int N,K,i,head,tail,x;
	scanf("%d %d",&N,&K);
	head=tail=0;//tail指向队尾元素的下一个位置
	for(i=0;i<N;i++){
		scanf("%d",&x);
		if(head<tail&&que[head].index<=i-K) head++;//如果队首的元素到队尾大于或等于K个,则T掉队首元素,因为当前元素一定要加入队列。
		while(head<tail&&que[tail-1].val>=x)//队首存放最小值。
			tail--;
		que[tail].val=x;
		que[tail++].index=i;
		ans[i]=que[head].val;
	}
	for(i=K-1;i<N;i++)
		printf("%d ",ans[i]);
	printf("\n");
	return 0;
}


 

### 回答1: 好的,以下是一个简单的单调队列模板的 C 语言代码模板: ``` #include <stdio.h> #define MAX_N 100000 int a[MAX_N]; // 存储原始数据 int q[MAX_N]; // 存储队列元素下标 int head = 0, tail = 0; // 队列头尾指针 int main() { int n, k; // n 表示数组长度,k 表示窗口长度 scanf("%d%d", &n, &k); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } // 处理前 k 个元素 for (int i = 0; i < k; i++) { while (tail > head && a[q[tail - 1]] >= a[i]) { tail--; // 弹出队尾元素 } q[tail++] = i; // 将当前元素下标加入队尾 } // 处理剩余元素 for (int i = k; i < n; i++) { printf("%d ", a[q[head]]); // 输出队头元素 // 弹出超出窗口范围的队头元素 if (q[head] == i - k) { head++; } // 弹出队尾元素,直到队列为空或者队尾元素小于当前元素 while (tail > head && a[q[tail - 1]] >= a[i]) { tail--; } q[tail++] = i; // 将当前元素下标加入队尾 } printf("%d\n", a[q[head]]); // 输出最后一个窗口的最小值 return 0; } ``` 这是一个简单的使用单调队列求解滑动窗口最小值的模板。当然,具体实现还需要结合具体问题来进行修改和优化。 ### 回答2: 单调队列(Monotonic Queue)是一种在数据结构中常见的一种队列,它支持在队列两端进行元素的插入和删除操作,但新增的元素必须按照一定的顺序排列。 以下是一个用C语言实现的单调队列模板: ```c #include <stdio.h> #define MAX_SIZE 100 // 单调队列结构体 typedef struct { int arr[MAX_SIZE]; // 存储队列元素的数组 int front; // 队列头指针 int rear; // 队列尾指针 } MonotonicQueue; // 初始化单调队列 void initQueue(MonotonicQueue *q) { q->front = q->rear = -1; } // 判断队列是否为空 int isEmpty(MonotonicQueue *q) { return q->front == -1; } // 判断队列是否已满 int isFull(MonotonicQueue *q) { return (q->rear + 1) % MAX_SIZE == q->front; } // 元素入队(从队尾插入) void enqueue(MonotonicQueue *q, int x) { if (isFull(q)) { printf("Queue is full.\n"); return; } if (isEmpty(q)) { q->front = q->rear = 0; } else { q->rear = (q->rear + 1) % MAX_SIZE; } q->arr[q->rear] = x; } // 元素出队(从队首删除) void dequeue(MonotonicQueue *q) { if (isEmpty(q)) { printf("Queue is empty.\n"); return; } if (q->front == q->rear) { q->front = q->rear = -1; } else { q->front = (q->front + 1) % MAX_SIZE; } } // 获取队首元素 int front(MonotonicQueue *q) { if (isEmpty(q)) { printf("Queue is empty.\n"); return -1; } return q->arr[q->front]; } // 获取队尾元素 int rear(MonotonicQueue *q) { if (isEmpty(q)) { printf("Queue is empty.\n"); return -1; } return q->arr[q->rear]; } int main() { MonotonicQueue q; initQueue(&q); enqueue(&q, 1); enqueue(&q, 2); enqueue(&q, 3); printf("Front element: %d\n", front(&q)); // Output: Front element: 1 printf("Rear element: %d\n", rear(&q)); // Output: Rear element: 3 dequeue(&q); printf("Front element: %d\n", front(&q)); // Output: Front element: 2 return 0; } ``` 这个单调队列模板包含了初始化队列、判断队列是否为空、判断队列是否已满、元素入队、元素出队、获取队首元素和获取队尾元素等基本操作。使用时,只需要调用相应的函数即可实现单调队列的各种操作。 ### 回答3: 单调队列是一种特殊的队列数据结构,它在插入和删除元素时保持队列中元素的单调性。 以下是一个用C语言编写的单调队列模板: ```c #include <stdio.h> #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; // 存储数据 int front, rear; // 队首和队尾指针 } MonotonicQueue; // 初始化队列 void init(MonotonicQueue* q) { q->front = 0; q->rear = -1; } // 判断队列是否为空 int isEmpty(MonotonicQueue* q) { return q->rear < q->front; } // 获取队首元素 int front(MonotonicQueue* q) { return q->data[q->front]; } // 在队尾插入元素 void push(MonotonicQueue* q, int x) { // 删除队尾小于x的元素,保持队列单调递增 while (!isEmpty(q) && q->data[q->rear] < x) { q->rear--; } q->rear++; q->data[q->rear] = x; } // 在队首删除元素 void pop(MonotonicQueue* q, int x) { if (!isEmpty(q) && q->data[q->front] == x) { q->front++; } } int main() { MonotonicQueue q; init(&q); // 示例使用 push(&q, 3); push(&q, 1); printf("队首元素为:%d\n", front(&q)); // 输出 3 pop(&q, 3); printf("队首元素为:%d\n", front(&q)); // 输出 1 return 0; } ``` 这个单调队列模板使用一个数组来存储队列中的数据,并使用front和rear两个指针来记录队首和队尾位置。通过初始化、判断为空、获取队首元素、插入元素和删除元素等基本操作,可以实现一个单调队列。在插入元素时,会删除队列中队尾小于插入元素的元素,从而保持队列的单调性。在删除元素时,会删除队首等于删除元素的元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值