[湖北2011寒假] 求M数

1141. [湖北2011寒假] 求M数

★   输入文件: allm.in   输出文件: allm.out    简单对比
时间限制:10 s   内存限制:128 MB

【题目描述】

n 个数排成一排。一个数的M 数是指的在这个数的左边且比它小的数中最靠近它(即
 最靠右)的那个数。依次给出这n 个数,请求出所有这n 个数相对应的M 数。

【输入格式】

从文件allm.in 中读入数据。
 数据的第一行是一个正整数n,表示一共有多少个数。
 第二行有n 个用空格隔开的正整数,它们从左至右给出了数列中的n 个数。这些数保证
 小于2^31。

【输出格式】

输出一行用空格隔开的n 个数到文件allm.out。
 这些数对应输入数据中的数的M 数。如果输入中某个数没有M 数(即它左边的数都不
 比它小),请输出0。

【样例输入】

7
3 1 2 7 6 7 4

【样例输出】

0 0 1 2 2 6 2

【提示】

对于100%的数据,有n<=1000000.


可以用线段树,但是用记忆化搜索实现比较简单点。 按题意开一个数组记录每个数左边最接近当前这个数的位置。下次搜索的时候直接跳转。

#include<cstdio>
using namespace std;
const int maxn = 1000000+100;
int a[maxn],pos[maxn],ans[maxn];
int main(){
    freopen("allm.in","r",stdin);
    freopen("allm.out","w",stdout);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) pos[i]=1;
    for(int i=1;i<=n;i++){
        int flag=0,index;
        for(int j=i-1;j>=1;j=pos[j]){
            if(a[j]<a[i]){
             flag=1;  index=j;
             break;
            }
        }
        if(flag){
           pos[i]=index;
           ans[i]=a[index];
        }
        else{
           pos[i]=0;
        }
    }
    for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    return 0;
}



你可能感兴趣的:([湖北2011寒假] 求M数)