Vertical Histogram HDU 2708 代码详解



Vertical Histogram

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2472    Accepted Submission(s): 536


Problem Description
Write a program to read four lines of upper case (i.e., all CAPITAL LETTERS) text input (no more than 72 characters per line) from the input file and print a vertical histogram that shows how many times each letter (but not blanks, digits, or punctuation) appears in the all-upper-case input. Format your output exactly as shown.
 

Input
* Lines 1..4: Four lines of upper case text, no more than 72 characters per line.
 

Output
* Lines 1..??: Several lines with asterisks and spaces followed by one line with the upper-case alphabet separated by spaces. Do not print unneeded blanks at the end of any line. Do not print any leading blank lines.
 

Sample Input
   
   
   
   
THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG. THIS IS AN EXAMPLE TO TEST FOR YOUR HISTOGRAM PROGRAM. HELLO!
 

Sample Output
   
   
   
   
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
 

Source
USACO 2003 February Orange
 

Recommend
teddy   |   We have carefully selected several similar problems for you:   2723  2709  2715  2721  2719 

注意输出格式,输完最后一个*号就不用输出空格了!!!用鼠标选中样例输出就会发现这一问题......

这两天都在纠结这个题 还有 4054 那个题怎么老是WA
这个题解是从讨论区看到的,改进了一下,看懂了后,加上了注释
至于自己的WA代码先贴上,后面有时间再回过头来看(没办法,赶进度最近)
AC如下:代码虽短,逻辑上有点不好理解,建议结合实例手动运行一遍

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

void print(int num)
{
    for (int i = 0; i < num; i++)
        printf(" ");
}
int main()
{
    char str[1000],a[100];
    int ncount[100];
    int i, j,nmax;
    while (gets(str))
    {
        memset(ncount,0,sizeof(ncount));
        for (j = 0; j < 3; j++)
        {
            gets(a);
            strcat(str,a);
        }

        for (i = 0; str[i]; i++)
        {
            if (str[i] >= 'A'&&str[i] <= 'Z')
                ncount[str[i] - 'A']++;
        }

        nmax = 0;
        for (i = 0; i<26; i++)
        {
            if (ncount[i]>nmax) nmax = ncount[i];
        }

        for (i = nmax; i >= 1; i--)//倒输、控制行
        {
            int num = 0;//用于计算需要补齐的空格个数
            for (j = 0; j < 26; j++)//控制列
            {
                if (ncount[j] >= i)//当遇到某个字母的个数大于等于该行号(这里的行号是做从下往上计数理解)时,说明此时前面需要补齐空格并在该列输出*
                {
                    print(num);//补齐num个空格————这空格计数器包括了每两个*号之间的空格
                    num = 0;   //空格计数器归0
                    printf("*");
                }
                else
                    num++;//若当前列不需要输出*,如果后面有*,那么这一列要输出空格,所以空格计数器加一,

                if (j != 25)
                    num++;//这是因为每一列之间中间还需要输出空格,所以也要计数
            }
            printf("\n");
        }
        for (i = 0; i < 26; i++)//输出最底行
        {
            printf("%c", i + 'A');
            if (i != 25)
                printf(" ");
        }
        printf("\n");
    }
    return 0;
}

////
////
WA代码(WA到哭。。。)
按理来说是没问题的...
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

char sum[28][400];
int flag[28];
int i,j,nmax;
char input[80];

void findMaxFlag(int n,int m)
{
    int i,nMax,k;

    if(n == m) return;

    nMax = flag[n];
    k = n;

    for(i = n + 1; i < m; i++)
    {
        if(flag[i] > nMax)
        {
            nMax = flag[i];
            k = i;
        }
    }

    for(i = n; i < k; i++)
    {
        flag[i] = nMax;
    }

    findMaxFlag(k + 1,m);
}

void countSum(char* s)
{
    int len,j,k;
    len = strlen(input);
    for(j = 0; j < len; j++)
    {
        if(input[j] >= 'A' && input[j] <= 'Z')
        {
            k = input[j] - 'A' + 1;
            sum[k][flag[k]] = '*';
            flag[k]++;
        }

    }
}
int main()
{
    while(gets(input) != NULL)
    {
        memset(flag,0,sizeof(flag));
        memset(sum,'\0',sizeof(sum));
        countSum(input);
        for(i = 1; i <= 3; i++)
        {
            gets(input);
            countSum(input);
        }

        findMaxFlag(1,27);

        for(i = 1; i < 27; i++)
            for(j = 0; j < flag[i]; j++)
            {
                if(sum[i][j] != '*') sum[i][j] = ' ';
            }

        nmax = flag[1];

        for(i = 2; i < 27; i++)
        {
            if(nmax < flag[i]) nmax = flag[i];
        }

        for(i = nmax - 1; i >= 0; i--)
        {
            for(j = 1; j < 27; j++)
            {
                cout << sum[j][i];
                if(j != 26 && i < flag[j + 1]) cout << ' ';
            }
            cout << endl;
        }

        cout<<"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"<<endl;

    }

    return 0;
}




 

你可能感兴趣的:(ACM,HDU,杭电)