NOJ [1021] Sliding Window

An array of size n ≤ 10^6 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example: 
The array is [1 3 -1 -3 5 3 6 7], and k is 3.

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.

题意很简单,求区间内的最值然后输出,rmq可以做


#include<stdio.h>
#include<math.h>

int min (int a,int b)
{
  return a<b?a:b;
}
int max(int a,int b)
{
	return a>b?a:b;
}
int num[1000010];
int dp[1000010][20];
int n;
void rmq1()
{
  int i,j;
  int k= log((double)(n+1))/log(2.0);
  for(i=1;i<=n;i++)
    dp[i][0]=num[i];
  for(j=1;j<=k;j++)
      for(i=1;i+(1 << j)-1 <= n;i++)
         dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}

void rmq2()
{
  int i,j;
  int k= log((double)(n+1))/log(2.0);
  for(i=1;i<=n;i++)
    dp[i][0]=num[i];
  for(j=1;j<=k;j++)
      for(i=1;i+(1 << j)-1 <= n;i++)
         dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int st1(int a,int b)
{
  int k = (int)(log((double)(b-a+1))/log(2.0));
  return min(dp[a][k],dp[b-(1<<k)+1][k]);
}

int st2(int a,int b)
{
  int k = (int)(log((double)(b-a+1))/log(2.0));
  return max(dp[a][k],dp[b-(1<<k)+1][k]);
}

int main()
{
  int k;
  while(~scanf("%d%d",&n,&k))
  {
    int i;
    for(i=1;i<=n;i++)
      scanf("%d",&num[i]);
    rmq1();
   
    for(i=1;i<=n-k+1;i++)
    {
      printf("%d", st1(i,i+k-1));
      if(i<=n-k)
      printf(" ");
    }
    printf("\n"); 
	rmq2();
    for(i=1;i<=n-k+1;i++)
    {
      printf("%d", st2(i,i+k-1));
      if(i<=n-k)
      printf(" ");
    }
    printf("\n");
  }
  return 0;
}


你可能感兴趣的:(NOJ [1021] Sliding Window)