回 帖 发 新 帖 刷新版面

主题:第51次编程比赛

题目:训练场上n(1≤n≤50000)个[b][color=FF0000]高矮都不相同[/color][/b]的士兵[b]从左到右[/b]排成一行,依次编号为1,2,…,n。第i个士兵的身高H(i),由于采用特殊单位,H(i)满足1≤H(i)≤2000000000。设第i个士兵右侧最近的比他个高的士兵编号为j,则第i个士兵可看到在他的右侧比他矮的士兵的个数S(i)=j-i-1。(不考虑客观因素,比如视力范围等-,-)
求S(1)+S(2)+…+S(n)。

输入:
标准输入。
第一行为整数n,表示士兵的个数。
第二行n个整数,用一个空格隔开。分别表示编号为1,2。。。n的士兵的身高

输出:
S(1)+S(2)+…+S(n)的结果

例:
输入
6
10 3 7 4 12 2
输出
5

例子说明:
S(1) = 3
S(2) = 0
S(3) = 1
S(4) = 0
S(5) = 1
S(6) = 0
S(1)+S(2)+S(3)+S(4)+S(5)+S(6) = 3+0+1+0+1+0 = 5

回复列表 (共65个回复)

51 楼

#include<iostream>
using namespace std;
long n;
long long heigh[50000];
long long total[50000];
int main()
{
    scanf("%d",&n);
    for (long a=1;a<=n;++a) scanf("%ld",&heigh[a]);
    total[n]=0;
    long b=0;
    for (long a=n-1;a>=1;--a) 
    {
        if (heigh[a]>heigh[a+1]) b=total[a+1]+a+1;else b=a+1;
        while ((heigh[a]>heigh[b])&&(b<=n)) ++b;
        total[a]=b-a-1;
    }
    long long ans=0;
    for (long a=1;a<=n;++a) ans+=total[a];
    printf("%ld",ans);
}

52 楼

#include <stdio.h>
#include <stdlib.h>
/*#include <time.h>*/
#define M 50000  /* 士兵人数 */
void arrin(unsigned long int *H)
{
 int i=0,j,x;
 while(i<M)
 {
  /*srand((unsigned)time(NULL)); 初始化随机种子*/
  x=(rand()%10000+1)*(rand()%10000+1)*(rand()%20+1); /*随机输出士兵身高*/
  j=0;
  while((j<i)&&(x!=H[j]))
  j++;
  if(j==i) H[i++]=x;
 }
}
/*输出H(i)身高。
void arrout(unsigned long int *H)
{
 int i;
 for(i=0; i<M; i++)
 printf("%-20d",H[i]);
 printf("\n");

*/
void arrsum(unsigned long int *H,unsigned int *S,unsigned int sum)
{
 unsigned int i=0,j;
 while(i<M)
 {
  for(j=i+1; j<M; j++)
  if(H[i]<H[j]) break;
  S[i]=j-i-1;
  sum+=S[i];
  i++;
 }
 printf("Sum=%d\n",sum);  /*输出S(n)总和*/
}
int main(void)
{
 unsigned long int H[M]={0},sum=0; /*H[M]是士兵身高,sum是能看到右侧士兵的总和*/
 unsigned int S[M];  /*S[M]是第i个士兵能看到右侧士兵的个数*/
 /*int start,finish;*/
 /*start=clock();开始时间*/
 arrin(H);  /*随机输入士兵H(i)身高*/
 /*arrout(H);输出H(i)身高。*/
 arrsum(H,S,sum);  /*输出能看到右侧士兵的总和*/
 /*finish=clock();结束时间*/
 /*printf("Time:%dms\n",finish-start);运行时间*/
 system("pause");
 return 0;
}

53 楼

int CountShort(int n,int height[])
{
    int *s=new int[n];
    memset(s,0,n*sizeof(int));
    for(int i=n-2;i>=0;i--)
       for(int k=i+1;k<=n-1;)
       {
           if(height[i]>height[k])
           {
             s[i]+=(s[k]+1);
               k+=(s[k]+1);
               }
             else
                break;
           }
       delete s;
       int sum(0);
       for(int i=0;i<n;i++)
          sum+=s[i];
       return sum;       
}

54 楼

#include <iostream>
using namespace std;

unsigned int S = 0;
unsigned int H[50000];

int main(int argc, char* argv[])
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>H[i];
        for(int j=i-1;j>=0;j--)
        {
            if(H[j])
            {
                if(H[j] > H[i])
                    S += 1;
                else
                    H[j] = 0;
            }
        }
    }
    cout<<S<<endl;
    return 0;
}

55 楼


#include<stdio.h>
main()
{
unsinded int i,j,m;
double flout H[50000],s[50000],S;
printf("输入士兵个数及每个士兵身高。\n");
scanf("%d",&i);       /*输入士兵个数*/
printf("\n");         
for(m=1;m<=i;m++)      /*输入士兵身高*/
scanf("%d "&H[i-1]);
for(m=1;m<=i;m++)
{fou(j=1;j<=i;j++)
  if(H[j-1]>H[i-1])       /*计算*/
    break;
  s(i-1)=j-i-1;
}
 for(S=0,m=1;m<=i;m++)
   S=S+s(i-1);
printf("%d",S);                /*输出结果*/
}

56 楼


int Insert(int n,int height[],int num)
{
    int low = 0,high = n-1;
    while(low<=high){
        int m = (low + high) / 2;
        if(height[m] > num)
            low = m + 1;
        else
            high = m - 1;
    }
    return high + 1;
}

int countHeight(int n,int height[])
{
    const int Max = 50000;            //最大士兵数
    int temp[Max];                    //保存递减序列
    temp[0] = height[0];
    int Up = 0;                        //序列的上界
    int result = 0;                    //返回值
    
    for(int i = 1;i<n;i++){
        if(height[i]>temp[0])        //下一个士兵高度大于序列中任一高度
            Up = 0;
        else if(height[i]<temp[Up])    //下一个士兵高度小于序列中任一高度
            ++Up;
        else                        //下一个士兵高度在序列中
            Up = Insert(Up+1,temp,height[i]);
        result += Up;
        temp[Up] = height[i];

    }
    return result;                
}

57 楼

//这下楼主要辛苦了,交卷的人那么多,而且这个题目还不好测试。
//对于{10, 3, 9, 2, 8, 4, 5};结果应为6+0+4+0+2+0=12,但是我下面注释起来的那个版本是8。
//楼主最好找几个帮手测试哦。
unsigned long Num_soldier_see(long total, long *height)
{
    static long *first[49998] = {0};//用malloc怕速度慢,不过49998写得我慌
    unsigned long sum = 0;
    long *second = height;
    long *third = height + 1;
    long NumCountinue = 0;
    long endPosition = -1;//记录在second前面的元素个数
    while (third != height + total)
    {
        if (*second > *third)
        {
            sum += ++NumCountinue;
            first[++endPosition] = second++;
            third++;
        }
        else
        {
            while (endPosition != -1)
            {
                if ( *(first[endPosition]) > *third)
                {
                    NumCountinue = endPosition + 1;
                    sum += NumCountinue;
                    second = third++;
                    break;
                }
                else
                {
                    endPosition--;
                }
            }
            if (endPosition == -1)
            {
                NumCountinue = 0;
                second = third++;
            }
        }
    }
    return sum;
}
/*
错误 !
unsigned long Num_soldier_see(long total, long *height)
{
    unsigned long sum = 0;
    long *first = height;
    long *second = height;
    long *third = height + 1;
    long NumCountinue = 0;
    while (third != height + total)
    {
        if (*second > *third)
        {
            sum += ++NumCountinue;
            second++;
            third++;
        }
        else
        {
            if (*first > *third)
            {
                NumCountinue = 1;
                sum += 1;
                second = third++;
            }
            else
            {
                first = second = third++;
                NumCountinue = 0;
            }
        }
    }
    return sum;
}*/

58 楼

我是57楼的,我的要改一下。
那个49998要改49999。。。
或者直接50000算了, 都50000了也不差那一点了。。。

59 楼

#include <stdio.h>
#include <stdlib.h>

// 起用以下语句,可以进入测试模式。使用两种不同算法计算结果,并判断改进算法是否有错
// 禁用以下语句,则为正式模式,提交用。
// #define TEST

#ifdef TEST
// cal_safe
// 采用保守算法,尽量追求正确
int cal_safe(int nSolders, const int* iHeight)
{
    int ret = 0;
    int i, j;
    for(i=0; i<nSolders; ++i)
    {
        for(j=i+1; j<nSolders && iHeight[i] > iHeight[j]; ++j)
        {
            ++ret;
        }
    }
    return ret;
}
#endif

// cal_fast
// 改进的算法,尽量追求快速
int cal_fast(int nSolders, const int* iHeight)
{
    int ret = 0;
    int i, j, k;
    int* tmp = (int*)calloc(nSolders, sizeof(int));
    int  tmp_count = 0;
    // 检查所有士兵,将身高比左边一个高的记录到数组tmp中
    for(i=1; i<nSolders; ++i)
        if( iHeight[i] > iHeight[i-1] )
            tmp[tmp_count++] = i;
    // 对每一士兵,只检查右边所有身高有增高趋势的士兵
    k = 0;
    for(i=0; i<nSolders; ++i)
    {
        while( k < tmp_count && tmp[k] < i )
            ++k;
        for(j=k; j<tmp_count; ++j)
        {
            if( iHeight[i] < iHeight[tmp[j]] )
                break;
        }
        if( j<tmp_count )
            ret += (tmp[j]-i-1);
        else
            ret += nSolders-i-1;
    }

    free(tmp);
    return ret;
}

int main(void)
{
#ifndef TEST
    int nSolders, i;
    int* iHeight;
    scanf("%d", &nSolders);
    iHeight = (int*)malloc(nSolders*sizeof(int));
    for(i=0; i<nSolders; ++i)
        scanf("%d", &(iHeight[i]));
    printf("%d\n", cal_fast(nSolders, iHeight));
    free(iHeight);
#else
    int nSolders;
    static int iHeight[50000];
    int samples, i;
    int nError = 0;
    for(samples=0; samples<1000; ++samples)
    {
        int a, b;
        nSolders = rand() % 50000 + 1;
        // 取得nSolders个不同的数值作为身高
        for(i=0; i<nSolders; ++i)
            iHeight[i] = i + 1;
        for(i=0; i<1000; ++i)
        {
            int tmp;
            a = rand() % nSolders;
            b = rand() % nSolders;
            tmp = iHeight[a];
            iHeight[a] = iHeight[b];
            iHeight[b] = tmp;
        }
        // 两种方式计算结果
        a = cal_safe(nSolders, iHeight);
        b = cal_fast(nSolders, iHeight);
        if( a != b )
        {
            printf("error.\n");
            ++nError;
        }
    }
    printf("there are %d error(s).\n", nError);
#endif
    return 0;
}

60 楼

#include "stdio.h"

typedef unsigned int U32;

enum
{
    ERR_OK,
    ERR_PARAM,
};


int P51(int n, U32 *height);

void main()
{
/*    int n = 6;
    U32 height[] = {10, 3, 7, 4, 12, 2};
*/
    int n = 20;
    U32 height[] = {2000000000, 200000001, 20000001, 2000001, 200001, 20001, 2001, 201, 21, 2,
                    5, 2, 200002, 200001, 200000, 20000, 2000, 200, 20, 2};
    P51(n, height);
}

int P51(int n, U32 *height)
{
    static U32 s[50000] = {0};
    U32 sum = 0;
    int i = 0, j = 0;

    if ((n <= 0) || (height == NULL))
        return ERR_PARAM;

    s[n - 1] = 0;
    /* from right to left */
    for (i = n - 2; i >= 0; i--)
    {
        /* not higher than his right */
        if (height[i] <= height[i + 1])
        {
            s[i] = 0;
        }
        else /* higher than his right */
        {
            j = i + 1;

            while ((j < n) && (height[i] > height[j]))
            {
                s[i] += s[j] + 1;
                j += s[j] + 1; 
            }

            sum += s[i];
        }
    }

    printf("%u\n", sum);

    return ERR_OK;
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册