Function(HDU5875)

来源:互联网 发布:优化软件下载 编辑:程序博客网 时间:2024/05/16 17:19

大连网络赛。当时挺混乱的,其实根本都没看这道题。后来看了题解觉得用的方法很巧妙。

值得学习。

同时回忆起一道以前的题目。

用的都是类似的思想。

#include<bits/stdc++.h>using namespace std;#define inf 0x3f3f3f3fint t,n,q,l,r,ans,modpos;int a[100005];int rightpos[100005];int main(){    scanf("%d",&t);    while(t--)    {        cin>>n;        for(int i=1; i<=n; i++)            scanf("%d",&a[i]);        memset(rightpos,inf,sizeof(rightpos));        for(int i=n-1; i>=1; i--)        {            int k=i+1;            while(1)            {                if(a[i]>a[k]) //找到右边的数比自己小,对答案有影响,存下这个位置                {                    rightpos[i]=k;                    break;                }                if(rightpos[k]==inf)//找到最后                    break;                k=rightpos[k];            }        }        scanf("%d",&q);        while(q--)        {            scanf("%d%d",&l,&r);            ans=a[l];            modpos=rightpos[l];            while(modpos<=r)            {                ans%=a[modpos];                if(ans==0)                    break;                modpos=rightpos[modpos];            }            printf("%d\n",ans);        }    }    return 0;}
思路很简单,就是一直找右边的第一个比这个数小的数。然后不断的存起来,从左往右更新是n^2,从右往左更新最差是n。思路很巧妙,不断的递归往右侧找第一个出现的,小于当前位置的这个数的位置。

当时第一次启蒙我的题目是

the nearest taller cow

题目是在牛的左侧或者右侧找到最近的一个比自己高的牛的位置。然后求平均值。

也是用的类似的方法,从前往后更新出每个点往左边的第一个比他大的值。

在从右往左更新出在右边的第一个比这个数大的值。

最后求和求平均值

#include<bits/stdc++.h>using namespace std;#define inf 0x3f3f3f3f#define eps 1e-7int n,pos;int a[1000005];int rightpos[1000005],leftpos[1000005];double  ans;int main(){    while(~scanf("%d",&n))    {        ans=0;        for(int i=1; i<=n; i++)            scanf("%d",&a[i]);        a[0]=inf;        a[n+1]=inf;        memset(rightpos,inf,sizeof(rightpos));        memset(leftpos,inf,sizeof(leftpos));        for(int i=1; i<=n; i++)        {            pos=i-1;            while(a[pos]<=a[i])                pos=leftpos[pos];            leftpos[i]=pos;        }        for(int i=n; i>=1; i--)        {            pos=i+1;            while(a[pos]<=a[i])                pos=rightpos[pos];            rightpos[i]=pos;        }        for(int i=1; i<=n; i++)        {            //cout<<leftpos[i]<<" "<<rightpos[i]<<endl;            if(leftpos[i]==0)                leftpos[i]=-inf;            if(rightpos[i]==n+1)                rightpos[i]=inf;            ans+=min(min(i-leftpos[i],rightpos[i]-i),n);        }        //cout<<ans<<endl;        printf("%.2f\n",ans/n+eps);    }    return 0;}





1 0
原创粉丝点击