• 编程爱好者论坛第六次编程比赛题目


    题目原文地址
    http://www.programfan.com/club/showbbs.asp?id=126227

    一、按要求编写以下函数。
    功能:    将给定缓冲区中的#字符移到字符串尾部
    函数名称:changetotail
    入口参数:psztext指向字符缓冲区的指针,以0结尾。
    出口:    psztext所指缓冲区中的#字符被移到缓冲区尾部
    返回值:  在出口缓冲区中第一个#的位置,若缓冲区中无#字符则返回 -1

    说明: 如传入("#W#W#W#WW#") 则传出时应转换为"WWWWW#####"并且返回值为 5
          如传入("1#2#3#")      则传出时应转换为"123###"并且返回值为 3


    // 1
    #include <stdio.h>

    int changetotail(char *psztext)
    {
        
    const char *= psztext;
        
    char *p2 = psztext;
        
    int ret;
        
        
    if (p == NULL)
            
    return -1;
        
        
    while(*p2 = *p++)
            
    *p2 != '#' && p2++;
        
        ret 
    = p2 == --? -1 : p2 - psztext;
        
        
    while(p2 < p)
            
    *p2++ = '#';
        
        
    return ret;
    }

    int main()
    {
        
    int i;
        
    char s[][16= 
        
    {
            
    "asdf#@",
            
    "#@",
            
    "###",
            
    "",
            
    "#D#D#D#D",
            
    "D#D#D#D#D",
            
    "#D#D#D#D#",
            
    "D#D#D#D",
            
    "######DDDD",
            
    "DDDD######",
        }
    ;
        
    for (i = 0; i < 10; i ++)
        
    {
            printf(
    "Case %d\n%s\n", i, s[i]);
            printf(
    "%s\n%d\n", s[i], changetotail(s[i]));
        }

        
        
    return 0;
    }


    第2题
    二、任给 1<=n<=20 个不同的非零正整数,每个正整数最多使用1次,请问这n个正整数能够加和的结果共有多少种(不考虑和超出long的最大值的可以),
    程序中请实现如下函数。用于计算数组data,中ncount的加和的数量。
    long getsumcount(long data[], long count);
    程序中可以出现别的辅助函数。或辅助结构等。

    例如,
    data[] = {1,2,3,4};
    ncount = 4;
    函数返回 10

    分解如下。(0不算)

    1  = 1
    2  = 2
    3  = 3 = 1+2
    4  = 4 = 1+3

    5  = 2+3 = 1+4
    6  = 2+4 = 1+2+3
    7  = 3+4 = 1+2+4
    8  = 1+3+4
    9  = 2+3+4
    10 = 1+2+3+4
    如上。所以结果是10种可能。

    我的方法基本思想是把已经出现过的数字用一个位1来标记。避免做对一个数字是否存在的查找操作。
    但long范围内要把所有的位都存下来,需要内存太大。2^32/8 byte = 512 MB
    所以改为分段保存,连续的32768位存在一起。对连续32768个数字都没有出现过的情况则不记录这块数据
    下面是我的程序:

    // 2

    #include 
    <vector>
    #include 
    <algorithm>
    using namespace std;
    class Set
    {
        typedef unsigned 
    long Int;
        
    struct bitSet // 存32768位
        {
            Int 
    base// 一个bitSet保留从base位开始的32768位标记
            Int buf[1024]; // 32*1024=32768位,这个大小其实是随意设的
            bitSet(Int b):base(b)
            
    {
                memset(buf, 
    0sizeof(buf));
            }

            
    void set(Int n)
            
    {
                Int d 
    = n - base;
                buf[d
    >>5|= 1 << (d & 0x1f); // 对第n位置位
            }

            
    bool test(Int n) const
            
    {
                Int d 
    = n - base;
                
    return (buf[d>>5& (1 << (d & 0x1f))) != 0// 判断第n位。
            }

            
    struct Ptr // 这个是为了堆排序不用排bitSet对象(bitSet的体积比较大),排Ptr对象其实就是指针排序
            {
                Ptr(bitSet 
    *pp = NULL):p(pp){}
                
    bool operator < (const Ptr &o) const // 提供对bitSet的排序关系
                {
                    
    return p->base < o.p->base;
                }

                bitSet 
    *p;
            }
    ;
        }
    ;
    public:
        
    ~Set()
        
    {
            
    for (vector< bitSet::Ptr >::iterator b = bits.begin(); b != bits.end(); b++)
                delete b
    ->p; // 不要忘了释放空间
        }

        
    void add(Int n)
        
    {
            bitSet::Ptr bs 
    = find(n);
            
    if (bs.p == NULL) // 如果整个bitSet块都不存在,那么得添加一个新的块了
            {
                Int 
    base = n & ~0x7fff;
                bs.p 
    = new bitSet(base);
                bits.push_back(bs);
                push_heap(bits.begin(), bits.end());
            }

            
    if (!bs.p->test(n)) // 如果这个位已经标记过,那么不应该添加到values内
            {
                bs.p
    ->set(n);
                values.push_back(n);
            }

        }

        
    bool test(Int n)
        
    {
            bitSet::Ptr bs 
    = find(n);
            
    if (bs.p == NULL)
                
    return false;
            
    return bs.p->test(n);
        }

        
    const vector< Int > &getValues() const {return values;}
    protected:
        bitSet::Ptr find(Int n) 
    const
        
    {
            typedef vector
    < bitSet::Ptr >::size_type size_t;
            Int 
    base = n & ~0x7fff;
            size_t d 
    = 0;
            
    const size_t size = bits.size();
            vector
    < bitSet::Ptr >::const_iterator b = bits.begin(), e = bits.end();
            
    while(d < size && b[d].p->base != base// 最大堆查找算法。本来想stl内找,貌似没有,就人肉做一个了
            {
                
    if (b[d].p->base < base)
                    d 
    = d*2 + 1;
                
    else
                    d 
    = (d+1)*2;
            }

            
    if (d >= size)
                
    return bitSet::Ptr(); // 找不到返回NULL指针对象
            return b[d];
        }

        vector
    < bitSet::Ptr > bits;
        vector
    < Int > values;
    }
    ;

    long getsumcount(long data[], long count)
    {
        Set 
    set;
        
    set.add(0); // 初始得有个0,便于下面代码统一
        for (int i = 0; i < count; i++)
        
    {
            vector
    < Set::Int >::const_iterator n;
            vector
    < Set::Int > newInt;
            
    const vector< Set::Int > &= set.getValues();
            
    for (n = v.begin(); n != v.end(); n++)
            
    {
                
    if (!set.test(*+ data[i])) // 对每个数字,如果加新数字的和不在集合内,那么准备添加到集合内
                    newInt.push_back(*+ data[i]);// 之所以这里不直接添加到set内,是因为v就是set内的values,如果这里对set的values做增加元素,将导致迭代器n失效。
            }

            
    for (n = newInt.begin(); n != newInt.end(); n++)
            
    {
                
    set.add(*n); // 把新的元素添加进去。
            }

        }

        
    return set.getValues().size() - 1// 最后去掉元素0
    }

    int main()
    {
        
    long data[] = 
        
    {
            
    0x1,0x2,0x4,0x8,
                
    0x10,0x20,0x40,0x80,
                
    0x100,0x200,0x400,0x800,
                
    0x1000,0x2000,0x4000,0x8000,
                
    0x10000,0x20000,0x40000,0x80000,
        }
    ;
        
        printf(
    "%d\n", getsumcount(data, 20));

        
    return 0;
    }


  • 相关阅读:
    qemu-img 整理
    学习 Spring (七) Resource
    学习 Spring (七) Resource
    ASP.NET 文件上传类 简单好用
    IOS之UIStepper控件详解
    IOS颜色块设置
    IOS之GCD记录
    ios项目中引用其他开源项目
    IOS之pageControl
    UI常用字体定义和继承的实例,ResearchKitCode
  • 原文地址:https://www.cnblogs.com/kaikai/p/290601.html
Copyright © 2020-2023  润新知