标题: 几道编程题
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-5-29 07:53 资料 文集 短消息 看全部作者


QUOTE:
原帖由 周瑜 于 2010-5-25 04:43 发表
01 链式开关

我的理解有问题吗,怎么感觉就是一个二进制进位?直接根据k输出各位的值就可以了。


顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-5-29 10:07 资料 文集 短消息 看全部作者


QUOTE:
原帖由 周瑜 于 2010-5-25 04:45 发表
主题公园

算法上没仔细考虑,-O2在atom1.6上要20s,超时了,找个好机器试试。。。

#include <fstream>
#include <sstream>
#include <string>
#include <vector>

typedef std::vector<int> TIntVector;

__int64 Calc(TIntVector const& Group, int R, int k)
{
        __int64 Total = 0;
        TIntVector Step;
        TIntVector Count;
        int const GroupSize = Group.size();

        Step.resize(GroupSize);
        Count.resize(GroupSize);

        for (int i = 0; i < GroupSize; ++i)
        {
                int ItStep = 0;
                int ItCount = 0;

                for (int j = 0; j < GroupSize; ++j)
                {
                        int Sub = i + j;

                        if (Sub >= GroupSize)
                        {
                                Sub -= GroupSize;
                        }

                        if (ItCount + Group[Sub] <= k)
                        {
                                ++ItStep;
                                ItCount += Group[Sub];
                        }
                        else
                        {
                                break;
                        }
                }

                Step[i] = ItStep;
                Count[i] = ItCount;      
        }

        if (GroupSize == Step[0])
        {
                Total = Count[0] * static_cast<__int64>(R);
        }
        else
        {
                int Next = 0;

                for (int i = 0; i < R; ++i)
                {
                        Total += Count[Next];
                        Next += Step[Next];

                        if (Next >= GroupSize)
                        {
                                Next -= GroupSize;
                        }
                }
        }

        return Total;
}

int main()
{
        std::ifstream In("in.txt");
        std::ofstream Out("testout.txt");
        std::string Line;
        int T = 0;

        In >> T;

        for (int i = 0; i < T; ++i)
        {
                int R = 0;
                int k = 0;
                int N = 0;

                In >> R;
                In >> k;
                In >> N;

                int Value;
                TIntVector Group;

                for (int j = 0; j < N; ++j)
                {
                        In >> Value;
                        Group.push_back(Value);
                }

                __int64 Result = Calc(Group, R, k);

                Out << "Case #" << i + 1 << ": " << Result << std::endl;
        }

        return 0;
}

[ 本帖最后由 Maxwell 于 2010-5-29 11:01 编辑 ]


顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-5-29 10:29 资料 文集 短消息 看全部作者
找了个2G的台式机试了试,11s。。。
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-5-29 11:06 资料 文集 短消息 看全部作者


QUOTE:
原帖由 周瑜 于 2010-5-29 10:56 发表
第1题并不是输出第k位,而是要求最低k位全是1。

第3题程序有点小错误,最后的
if (k == Step)
应改为
if (GroupSize == Step)

11秒已经是比较好的成绩了,但是算法上还有可以改进的地方,比换好机器管 ...

第1题没仔细看题,以为Case #x是第x位了。。。O(1)的题太少见了。。。

嗯,是写错了,测试用例里正好没有能暴露问题的用例,结果没发现。。。还是不太适应这种竞赛性质的题,一堆单字母一会儿就晕了。。。
作为懒的借口,我强调符合要求就好回头仔细想想算法去

[ 本帖最后由 Maxwell 于 2010-5-29 11:12 编辑 ]
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-5-29 11:54 资料 文集 短消息 看全部作者


QUOTE:
原帖由 周瑜 于 2010-5-25 04:45 发表
主题公园

一个新算法,复杂度似乎小于3N。
其它部分不变,改为调用Calc2即可。程序一闪就结束了,无法计时。
这段程序一次写成,没有经过调试,不保证在任何情况下都正确。
-----------------
上面的复杂度有问题。。。中午出了门想起来不对了,这个算法第一个循环还是O(N^2)的,不过可以改进到O(N),大约是4N。代码不写了,只要缓存计算结果就可以。

__int64 Calc2(TIntVector const& Group, int R, int k)
{
        __int64 Total = 0;
        TIntVector Step;
        TIntVector Count;
        int const GroupSize = Group.size();

        Step.resize(GroupSize);
        Count.resize(GroupSize);

        for (int i = 0; i < GroupSize; ++i)
        {
                int ItStep = 0;
                int ItCount = 0;

                for (int j = 0; j < GroupSize; ++j)
                {
                        int Sub = i + j;

                        if (Sub >= GroupSize)
                        {
                                Sub -= GroupSize;
                        }

                        if (ItCount + Group[Sub] <= k)
                        {
                                ++ItStep;
                                ItCount += Group[Sub];
                        }
                        else
                        {
                                break;
                        }
                }

                Step[i] = ItStep;
                Count[i] = ItCount;
        }

        if (GroupSize == Step[0])
        {
                Total = Count[0] * static_cast<__int64>(R);
        }
        else
        {
                std::vector<__int64> PreCount;
                TIntVector PreR;
                TIntVector FlagN;
                int Next = 0;
                __int64 ItPreCount = 0;
                int ItPreR = 0;
                __int64 CycleCount = 0;
                int CycleR = 0;
                int TailNext = 0;
                bool Finish = true;

                PreCount.resize(GroupSize);
                PreR.resize(GroupSize);
                FlagN.resize(GroupSize);

                for (int i = 0; i < R; ++i)
                {
                        if (0 == FlagN[Next])
                        {
                                PreCount[Next] = Total;
                                PreR[Next] = i;
                                FlagN[Next] = 1;

                                Total += Count[Next];
                                Next += Step[Next];

                                if (Next >= GroupSize)
                                {
                                        Next -= GroupSize;
                                }
                        }
                        else
                        {
                                ItPreCount = PreCount[Next];
                                ItPreR = PreR[Next];
                                CycleCount = Total - ItPreCount;
                                CycleR = i - ItPreR;
                                TailNext = Next;
                                Finish = false;

                                break;
                        }
                }

                if (!Finish)
                {
                        __int64 Tail = 0;

                        for (int i = 0; i < ((R - ItPreR) % CycleR); ++i)
                        {
                                Tail += Count[TailNext];
                                TailNext += Step[TailNext];

                                if (TailNext >= GroupSize)
                                {
                                        TailNext -= GroupSize;
                                }
                        }

                        Total = ItPreCount + (R - ItPreR) / CycleR * static_cast<__int64>(CycleCount) + Tail;
                }
        }

        return Total;
}

[ 本帖最后由 Maxwell 于 2010-5-29 18:51 编辑 ]
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-5-29 18:46 资料 文集 短消息 看全部作者
上面的复杂度有问题。。。中午出了门想起来不对了,这个算法第一个循环还是O(N^2)的,不过可以改进到O(N),大约是4N。代码不写了,只要缓存计算结果就可以。
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-5-30 21:10 资料 文集 短消息 看全部作者


QUOTE:
原帖由 周瑜 于 2010-5-25 04:44 发表
02 太空观测

这个题如果我没理解错的话,主要难度在大数运算上,不过可以全用减法,程序简单。10^50不到180位,6个32位或者3个64位就够了。按说明看应该输入是降序排序的,不过示例输入值有从大到小的也有从小到大的,关键是没说是不是保证有序的,从示例也看不出来。
但是全用减法速度上不去,实现个除法比较好。

[ 本帖最后由 Maxwell 于 2010-5-30 21:27 编辑 ]
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-5-31 12:12 资料 文集 短消息 看全部作者


QUOTE:
原帖由 周瑜 于 2010-5-31 03:13 发表
可能是我描述的不够清楚,已把题目改为“整数ti,表示过去的某次事件到现在的时间。”ti未必有序,也未必互不相等,但不会全相等。

后来想了一下,是否排序无所谓。不过两个相等的数值代表什么含义呢,是两次同时发生的事件还是重复数据?
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-6-1 09:20 资料 文集 短消息 看全部作者


QUOTE:
原帖由 周瑜 于 2010-6-1 03:19 发表


是重复数据。其实这完全是干扰条件,只是手头拿到的数据就有重复的。

乍想一下,似乎除法挺复杂,但是只用减法差不多要O(ti)了。有空先写个减法的试试,除法的慢慢想。另外,第3题用怎么用二分法能给讲讲不?我没想出来对谁二分。
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-6-3 18:44 资料 文集 短消息 看全部作者


QUOTE:
原帖由 周瑜 于 2010-5-25 04:44 发表
02 太空观测

尝试写了一个大数类,只实现了减法,发现效率实在太低,除法没时间写了。下面的代码是gcc+gmp写的,恐怕不是出题的原意了。

#include <fstream>
#include <string>
#include <vector>
#include <gmp.h>
#include <gmpxx.h>


typedef std::vector<mpz_class> TMpzVector;

mpz_class Calc1(TMpzVector const& Data)
{
        mpz_class MinTime = Data[0];
        mpz_class MinGcd = 0;
        size_t const DataLen = Data.size();

        for (size_t i = 1; i < DataLen; ++i)
        {
                mpz_class Diff = abs(Data[0] - Data[i]);

                if (Diff > 0)
                {
                        if (0 == MinGcd)
                        {
                                MinGcd = Diff;
                        }
                        else
                        {
                                mpz_class Gcd;

                                mpz_gcd(Gcd.get_mpz_t(), Diff.get_mpz_t(), MinGcd.get_mpz_t());
                               
                                if (Gcd < MinGcd)
                                {
                                        MinGcd = Gcd;
                                }
                        }
                }

                if (Data[i] < MinTime)
                {
                        MinTime = Data[i];
                }
        }

        mpz_class R = MinTime % MinGcd;
        mpz_class Ret;
       
        if (0 == R)
        {
                Ret = 0;
        }
        else
        {
                Ret = MinGcd - R;
        }

        return Ret;
}


int main()
{
        std::ifstream In("in.txt");
        std::string Line;
        int T = 0;
        FILE* Out = fopen("testout.txt", "w");

        In >> T;

        for (int i = 0; i < T; ++i)
        {
                int N = 0;
                std::string Num;
                TMpzVector Data;

                In >> N;

                for (int j = 0; j < N; ++j)
                {
                        In >> Num;
                        Data.push_back(mpz_class(Num));
                }

                mpz_class Result = Calc1(Data);

                gmp_fprintf(Out, "Case #%d: %Zd\n", i + 1, Result.get_mpz_t());
        }

        return 0;
}

顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-11-27 12:09 资料 文集 短消息 看全部作者


QUOTE:
原帖由 zhaohaidao 于 2010-10-23 18:12 发表

000000000000000000100 的情况下,此时电流到了第四个开关,题目说按一下按钮可以让所有通电开关翻转一次,电流到了第四个开关,那第三个跟第四个开关变不变呢?


0100的情况下电流到不了第4个开关只到第1个开关,0111的时候电流才到第4个开关。
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2011-4-3 04:31 资料 文集 短消息 看全部作者
02 太空观测



import re

def gcd(x, y) :
    while 0 != y :
        x, y = y, x % y

    return x

def gcd_list(l) :
    while len(l) > 1 :
        x = l.pop()
        y = l.pop()
        l.append(gcd(x, y))

    return l[0]

with open('in.txt') as in_file :
    x = in_file.readline()
    index = 0

    for line in in_file :
        index += 1
        l = re.findall(' \d+', line)
        g = gcd_list(list({abs(int(l[0]) - int(i)) for i in l if i != l[0]}))
        print('Case #{}: {}'.format(index, (g - int(l[0]) % g) % g))



[ 本帖最后由 Maxwell 于 2011-4-3 04:34 编辑 ]
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2011-4-3 12:27 资料 文集 短消息 看全部作者
04 翻转积木



def get_list(file) :
    [n, k] = map(int, file.readline().split(' '))
    l = []

    for i in range(0, n) :
        l.append([ch for ch in file.readline().strip()])

    return n, k, l

def turn_list(l) :
    n = len(l)

    for i in range(0, n) :
        for j in range(n - 1, -1, -1) :
            if '.' == l[i][j] :
                for k in range(j - 1, -1, -1) :
                    if '.' != l[i][k] :
                        l[i][j] = l[i][k]
                        l[i][k] = '.'
                        break

def find_h(l, x, y, ch, n) :
    for i in range(x + 1, x + n) :
        if ch != l[y][i] :
            return False
    return True

def find_v(l, x, y, ch, n) :
    for i in range(y + 1, y + n) :
        if ch != l[i][x] :
            return False
    return True

def find_lt_rb(l, x, y, ch, n) :
    for i in range(1, n) :
        if ch != l[y + i][x + i] :
            return False
    return True

def find_rt_lb(l, x, y, ch, n) :
    for i in range(1, n) :
        if ch != l[y + i][x - i] :
            return False
    return True

def find(l, x, y, ch, n) :
    size = len(l)
    d = {'h': False, 'v': False, 'r': False, 'l': False}

    if size - y >= n :
        d['v'] = True
        if size - x >= n :
            d['h'] = True
            d['r'] = True
        if x >= n - 1 :
            d['l'] = True
    else :
        if size - x >= n :
            d['h'] = True

    r = False

    if d['h'] :
        r = find_h(l, x, y, ch, n)
    if d['v'] and not r :
        r = find_v(l, x, y, ch, n)
    if d['r'] and not r :
        r = find_lt_rb(l, x, y, ch, n)
    if d['l'] and not r :
        r = find_rt_lb(l, x, y, ch, n)

    return r

def main() :
    with open('in03.txt') as in_file :
        t = int(in_file.readline())

        for i in range(1, t + 1) :
            n, k, l = get_list(in_file)
            turn_list(l)

            r = False
            b = False

            for y in range(0, n) :
                for x in range(0, n) :
                    if 'B' == l[y][x] and not b :
                        b = find(l, x, y, 'B', k)
                    elif 'R' == l[y][x] and not r :
                        r = find(l, x, y, 'R', k)

            if r and b :
                print('Case #{}: Both'.format(i))
            elif r :
                print('Case #{}: Red'.format(i))
            elif b :
                print('Case #{}: Blue'.format(i))
            else :
                print('Case #{}: Neither'.format(i))

main()



[ 本帖最后由 Maxwell 于 2011-4-3 21:05 编辑 ]
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2011-4-3 22:33 资料 文集 短消息 看全部作者
07 创建目录



def add(dir_tree, path) :
    l = path.split('/')
    d = dir_tree
    count = 0

    for item in l :
        if None == d.get(item) :
            d[item] = {}
            count += 1

        d = d[item]

    return count

def main() :
    with open('in07.txt') as in_file :
        T = int(in_file.readline())

        for i in range(1, T + 1) :
            dir_tree = {'': {}}
            count = 0
            [N, M] = map(int, in_file.readline().split(' '))

            for j in range(0, N) :
                add(dir_tree, in_file.readline().strip())

            for j in range(0, M) :
                count += add(dir_tree, in_file.readline().strip())

            print('Case #{}: {}'.format(i, count))            
            
main()

顶部

正在浏览此帖的会员 - 共 8 人在线




当前时区 GMT+8, 现在时间是 2025-1-2 20:06
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.012505 second(s), 9 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP