zoukankan      html  css  js  c++  java
  • HDU2019 数列有序!

    问题链接HDU2019 数列有序!入门训练题,用C语言编写程序。

    问题简述:参见上述链接。

    问题分析也许对于本题,会考虑用插入排序来做,那就有点绕远了。只要做排序就有可能可能做数据交换,处理时间就长了。

    可以考虑输入的n个数据先存放在数组中,再输出。

    各种方案中,一边输入数据,一边输出数据,并且在适当位置输出m的做法,应该是优选方案。因为这样做,省去了数组,没有使用额外空间。

    程序说明:(略)。

    AC的C语言程序如下(正解):

    /* HDU2019 数列有序! */
    
    #include <stdio.h>
    
    int main(void)
    {
        int n, m, val, i;
    
        while(scanf("%d%d", &n, &m) != EOF) {
            if(n == 0 && m == 0)
                break;
    
            if(n == 0) {
                // n=0时,只需要输出m
                printf("%d
    ", m);
            } else {
                // 读入n个数据,同时输出数据,并且在适当位置输出m
                int flag = 1;
                for(i=0; i<n; i++) {
                    scanf("%d", &val);
    
                    if(flag && val >= m) {
                        if(i == 0)
                            printf("%d", m);
                        else
                            printf(" %d", m);
                        flag = 0;
                    }
    
                    if(i>0 || !flag)
                        printf(" ");
                    printf("%d", val);
                }
                printf("
    ");
            }
        }
    
        return 0;
    }

    方案2:输入数据放到数组中,同时计数小于m的数据个数p,根据p值输出时在适当位置输出m。

    AC的C语言程序如下:

    /* HDU2019 数列有序! */
    
    #include <stdio.h>
    
    int main(void)
    {
        int n, m, a[100+1], i;
    
        while(scanf("%d%d", &n, &m) != EOF) {
            if(n == 0 && m == 0)
                break;
    
            if(n == 0) {
                // n=0时,只需要输出m
                printf("%d
    ", m);
            } else {
                // 读入n个数据
                int p = 0;
                for(i=0; i<n; i++) {
                    scanf("%d", &a[i]);
                    if(a[i] < m)
                        p++;
                }
    
                // 输出结果
                for(i=0; i<n; i++) {
                    if(i == p) {
                        if(i > 0)
                            printf(" ");
                        printf("%d", m);
                    }
                    if(i > 0 || i >= p)
                        printf(" ");
                    printf("%d", a[i]);
                }
                if(p == n) {
                    printf(" %d
    ", m);
                } else
                    printf("
    ");
            }
        }
    
        return 0;
    }

    方案3:输入数据时,将m与输入数据一起放入数组中,然后一起输出。这个方案的特点是输出部分逻辑相对简单。

    AC的C语言程序如下:

    /* HDU2019 数列有序! */
    
    #include <stdio.h>
    
    int main(void)
    {
        int n, m, a[100+1], i, j;
    
        while(scanf("%d%d", &n, &m) != EOF) {
            if(n == 0 && m == 0)
                break;
    
            if(n == 0) {
                // n=0时,只需要输出m
                printf("%d
    ", m);
            } else {
                // 读入n个数据到数组a,并且将m插入到a的适当位置
                int flag = 1;
                for(i=0,j=0; i<n; i++,j++) {
                    scanf("%d", &a[j]);
                    if(flag && a[j] > m) {
                        a[j+1] = a[j];
                        a[j] = m;
                        j++;
                        flag = 0;
                    }
                }
                if(i == j)  // m还没有插入到数组a中,则放在最后
                    a[n] = m;
    
                // 输出结果
                for(i=0; i<=n; i++) {
                    if(i > 0)
                        printf(" ");
                    printf("%d", a[i]);
                }
                printf("
    ");
            }
        }
    
        return 0;
    }

    方案4:先输入数据到数组中,然后用二分查找法找出m应该在的位置,然后输出结果。该方案逻辑太复杂,但是其逻辑也许有参考价值。

    AC的C语言程序如下:

    /* HDU2019 数列有序! */
    
    #include <stdio.h>
    
    int main(void)
    {
        int n, m, a[100+1], p, start, end, i;
    
        while(scanf("%d%d", &n, &m) != EOF) {
            if(n == 0 && m == 0)
                break;
    
            if(n == 0) {
                // n=0时,只需要输出m
                printf("%d
    ", m);
            } else {
                // 读入n个数据
                for(i=0; i<n; i++)
                    scanf("%d", &a[i]);
    
                // 用二分法找出m在a中的位置p,即满足a[p-1]<=m并且m<=a[p]
                // 需要考虑到特殊情况,即m在最前面(第1个)和m在最后面(第n个)的情况
                // 找到m在a中的位置后,不必将m插入到a中,只需要输出时在合适位置输出即可
                start = 0;
                end = n - 1;
                p = 0;
                while(start < end) {
                    p = (start + end) / 2;
                    if(a[p] == m)
                        break;
                    else if(a[p] < m)
                        start = ++p;    // 关键:改变start值的同时,要改变p值
                    else if(a[p] > m)
                        end = --p;      // 关键:改变end值的同时,要改变p值
                }
                if(a[p] < m)            // 关键:最后的调整
                    p++;
            }
    
            // 输出结果
            for(i=0; i<n; i++) {
                if(i == p) {
                    if(i > 0)
                        printf(" ");
                    printf("%d", m);
                }
                if(i > 0 || i >= p)
                    printf(" ");
                printf("%d", a[i]);
            }
            if(p == n) {
                printf(" %d
    ", m);
            } else
                printf("
    ");
        }
    
        return 0;
    }




  • 相关阅读:
    SGU 242. Student's Morning( 网络流 )
    8.23单词
    bzoj1083:繁忙的城市
    求连通分量
    bzoj2761:不重复数字
    bzoj1207:打鼹鼠
    bzoj2748:音量调节
    bzoj1050:旅行comf
    bzoj1996:合唱队
    羞耻羞耻羞耻!!!
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564679.html
Copyright © 2011-2022 走看看