题目描述:
Time Limit: 12000MS | Memory Limit: 65536K | |
Total Submissions: 16559 | Accepted: 4745 | |
Case Time Limit: 5000MS |
Description
Window position | Minimum value | Maximum value |
---|---|---|
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
Output
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
题意很简单,就是求区间的最大值和最小值。
我用线段树过的,直接改的以前的代码。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef struct{ int left,right; int Max,Min; } node; int tcase,n; int maxx,minn; node tree[1000001*4]; int a1[1000001],a2[1000001]; const int MAX = 999999999; const int MIN = -99999999; void build (int node,int left,int right) { tree[node].left=left; tree[node].right=right; tree[node].Max=MIN; tree[node].Min=MAX; if(left==right) return ; int mid; mid=(left+right)/2; build(node*2,left,mid); build(node*2+1,mid+1,right); } void update(int node,int pos,int val) { tree[node].Max=max(tree[node].Max,val); tree[node].Min=min(tree[node].Min,val); if(tree[node].left==pos&&tree[node].right==pos) return; int mid=(tree[node].left+tree[node].right)/2; if(pos<=mid) update(node*2,pos,val); else if(pos>mid) update(node*2+1,pos,val); return; } int query_max(int node,int left,int right) { if (tree[node].left == left && tree[node].right == right) return tree[node].Max ; if (tree[node].left > right || tree[node].right < left) return 0; int mid; mid=(tree[node].left + tree[node].right) / 2 ; if (right <= mid) return query_max(node * 2, left, right) ; else if (mid < left) return query_max(node * 2 + 1, left, right) ; else return max(query_max(node * 2, left, mid) ,query_max(node * 2 + 1, mid + 1, right)) ; } int query_min(int node,int left,int right) { if (tree[node].left == left && tree[node].right == right) return tree[node].Min ; if (tree[node].left > right || tree[node].right < left) return 0; int mid; mid=(tree[node].left + tree[node].right) / 2 ; if (right <= mid) return query_min(node * 2, left, right) ; else if (mid < left) return query_min(node * 2 + 1, left, right) ; else return min(query_min(node * 2, left, mid) ,query_min(node * 2 + 1, mid + 1, right)) ; } int main() { int i,j,x,y,k; scanf("%d %d",&n,&k); build(1,1,n); for(i=1;i<=n;i++) { scanf("%d",&x); update(1,i,x); } int num=0; for(i=1;i+k-1<=n;i++) { maxx=query_max(1,i,i+k-1); minn=query_min(1,i,i+k-1); a1[num]=maxx; a2[num++]=minn; } for(i=0;i<num-1;i++) printf("%d ",a2[i]); printf("%d\n",a2[num-1]); for(i=0;i<num-1;i++) printf("%d ",a1[i]); printf("%d\n",a1[num-1]); return 0; }
不过上网查了下 别人的代码,发现这题可以不用UPDATE函数,因为不需要数据的维护。
这题目还可以用单调队列。。。
http://blog.pureisle.net/archives/477.html
这个文章不错。