回 帖 发 新 帖 刷新版面

主题:第48次编程比赛结果

用户id          通过测试数(重复100次的时间):结果错误数:运行错误数
                第一题           第二题
neverPE:        101(16 ms):0:0   7(112 ms):0:0
ldb2741:        101(3515 ms):0:0 4(0 ms):97:0
rj1985:         101(62 ms):0:0   4(0 ms):97:0
dongch007:      101(188 ms):0:0  4(15 ms):97:0
user_09:        101(47 ms):0:0   4(0 ms):97:0
bpttc:          101(47 ms):0:0   3(0 ms):98:0
argentmoon:     101(47 ms):0:0   1(0 ms):100:0
zy1121:         101(63 ms):0:0   0(0 ms):101:0
user_06:        101(78 ms):0:0   0(0 ms):101:0
songfei:        101(3484 ms):0:0 0(0 ms):101:0
marry3640:      101(3750 ms):0:0 0(0 ms):101:0
bpttc2:         55(0 ms):46:0    3(32 ms):98:0
bloodybg:       40(374 ms):61:0  0(0 ms):101:0
hotzenplotz:    8(0 ms):93:0     0(0 ms):101:0
qqlxinye:       7(110 ms):94:0   0(0 ms):101:0

wshong 测试时间过长,被终止...
skybtone 测试中申请内存数量巨大且不释放,测试过程中由于内存申请导致虚拟内存不足死机状- -。后来

终于被我制服。提醒后人测试前至少粗略阅读一下被测代码以免受同样遭遇。

neverPE代码中可能是笔误把continue写成了break,改为continue后完全通过。其他代码有部分修改以便配

合编译器和测试环境(包括接口定义统一化,去除临时输出等)。

这次题目其实有些难度,如果误以为直接按题目所说的计算就可以就上当了。算法neverPE已经说出来了。
推倒过程略。

本次获胜者为neverPE,有请neverPE准备49次比赛:)并发表获奖感言~

附上我的代码,速度上没有neverPE的快,呵呵:(
[code]
#include <cstdio>
#include <cassert>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

namespace kaikai
{

static vector<int> primes;
bool IsPrime(int n)
{
     for(size_t i = 0; primes[i] * primes[i] <= n; i++)
     {
          if (n % primes[i] == 0)
               return false;
     }
     return true;
}

int GetPrime(size_t index)
{
     assert(index < 10000);
     
     if (index >= primes.size())
     {
          if (primes.size() == 0)
          {
               primes.reserve(10000);
               primes.push_back(2);
               primes.push_back(3);
               primes.push_back(5);
               primes.push_back(7);
          }
          for (int t = primes.back() + 2; index >= primes.size(); t += 2)
          {
               if (IsPrime(t))
                    primes.push_back(t);
          }
     }
     
     return primes[index];
}
int SumFactorMod(int n, int m, int s)
{
     vector<pair<int, size_t> > factors;
     int t;
     for(t = 0; n > 1; t++)
     {
          pair<int, size_t> factor(GetPrime(t), 0);
          while(n % factor.first == 0)
               n /= factor.first, factor.second++;
          if (factor.second)
               factors.push_back(factor);
     }
     int sum = 1;
     for (t = 0; t < factors.size(); t++)
     {
          const pair<int, size_t> &factor = factors[t];
          int d = 0, q = 1, maxi = factor.second * m;
          for (size_t i = 0; i <= maxi; i++)
          {
               d += q;
               d %= s;
               q *= factor.first;
               q %= s;
          }
          sum *= d;
          sum %= s;
     }
     return sum % s;
}
int SumFactorMod(int n, int s)
{
     return SumFactorMod(n, 1, s);
}
}
[/code]
附上测试代码:
[code]
#include <windows.h>
class Test
{
public:
     struct TestCase
     {
          int n, m, s;
          int out1, out2;
     };
     struct Testee
     {
          Testee():pF1(0), pF2(0), score1(0), score2(0), 
               wa1(0), wa2(0), wte1(0), wte2(0), time1(0), time2(0)
          {
          }
          int (*pF1)(int n, int s);
          int (*pF2)(int n, int m, int s);
          int score1, score2;
          int wa1, wa2;
          int wte1, wte2;
          int time1, time2;
          string name;
          bool operator < (const Testee &o) const
          {
               if (score1 == o.score1)
                    return time1 + time2 < o.time1 + o.time2;
               return score1 > o.score1;
          }
     };
     void AddTestee(int (*pF1)(int n, int s), int (*pF2)(int n, int m, int s), const char 

*name)
     {
          Testee testee;
          testee.pF1 = pF1;
          testee.pF2 = pF2;
          testee.name = name;
          testees.push_back(testee);
     }
     void AddTestCase(int n, int m, int s)
     {
          TestCase tc;
          tc.n = n;
          tc.m = m;
          tc.s = s;
          tc.out1 = GetSumOfFactor(n, 1, s);
          tc.out2 = GetSumOfFactor(n, m, s);
          testCases.push_back(tc);
     }
     void go()
     {
          for (int i = 0; i < testees.size(); i++)
          {
               Testee &testee = testees[i];
               printf("Testing %s", testee.name.c_str());
               for (int j = 0; j < testCases.size(); j++)
               {
                    if (j % 10 == 9)
                         printf(".");
                    const TestCase &testCase = testCases[j];
                    int o1 = -1, o2 = -1;
                    //printf("\n%d,%d,%d (%d %d)\n", testCase.n, testCase.m, 

testCase.s, testCase.out1, testCase.out2);
                    try
                    {
                         DWORD t1 = GetTickCount();
                         for (int k = 0; k < 25; k++)
                         {
                              o1 = testee.pF1(testCase.n, testCase.s);
                              o1 = testee.pF1(testCase.n, testCase.s);
                              o1 = testee.pF1(testCase.n, testCase.s);
                              o1 = testee.pF1(testCase.n, testCase.s);
                         }
                         DWORD t2 = GetTickCount();
                         if (o1 == testCase.out1)
                         {
                              testee.score1++;
                              testee.time1 += t2 - t1;
                         }
                         else
                         {
                              testee.wa1++;
                              //printf("o1 = %d\n", o1);
                         }
                    }
                    catch (...)
                    {
                         testee.wte1++;
                    }
                    try
                    {
                         DWORD t1 = GetTickCount();
                         for (int k = 0; k < 25; k++)
                         {
                              o2 = testee.pF2(testCase.n, testCase.m, 

testCase.s);
                              o2 = testee.pF2(testCase.n, testCase.m, 

testCase.s);
                              o2 = testee.pF2(testCase.n, testCase.m, 

testCase.s);
                              o2 = testee.pF2(testCase.n, testCase.m, 

testCase.s);
                         }
                         DWORD t2 = GetTickCount();
                         if (o2 == testCase.out2)
                         {
                              testee.score2++;
                              testee.time2 += t2 - t1;
                         }
                         else
                         {
                              testee.wa2++;
                              //printf("o2 = %d\n", o1);
                         }
                    }
                    catch (...)
                    {
                         testee.wte2++;
                    }
               }
               printf("\n");
          }
          sort(testees.begin(), testees.end());
          for (int i = 0; i < testees.size(); i++)
          {
               Testee &testee = testees[i];
               printf("%s:\t%d(%dms):%d:%d\t%d(%dms):%d:%d\n", testee.name.c_str(),
                    testee.score1, testee.time1, testee.wa1, testee.wte1,
                    testee.score2, testee.time2, testee.wa2, testee.wte2);
          }
     }
     vector<Testee> testees;
     vector<TestCase> testCases;
};
Test test;
#define TESTEE(a) test.AddTestee(a::SumFactorMod, a::SumFactorMod, #a)


int main()
{
     TESTEE(ldb2741);
     TESTEE(qqlxinye);
     TESTEE(user_06); // 雪光风剑
     // TESTEE(skybtone);  //内存爆裂弹- -
     TESTEE(user_09);// 独行者
     // TESTEE(wshong); // 疑似死循环
     TESTEE(bloodybg);
     TESTEE(bpttc);
     TESTEE(bpttc2);
     TESTEE(rj1985);
     TESTEE(marry3640);
     TESTEE(dongch007);
     TESTEE(argentmoon);
     TESTEE(songfei);
     TESTEE(hotzenplotz);
     TESTEE(zy1121);
     TESTEE(neverPE);
     //TESTEE(kaikai);

     test.AddTestCase(93, 113, 100);
     test.AddTestCase(93, 116, 7);
     srand(GetTickCount());
     for (int i = 0; i < 99; i++)
     {
          test.AddTestCase(rand() % 5000000, rand() % 5000000, rand() % 4999999+1);
     }
     test.go();
     return 0;
}
[/code]

回复列表 (共21个回复)

沙发

哦,结果中
user_06 是 雪光风剑
user_09 是 独行者

板凳

啊。。。

3 楼

辛苦了

4 楼

数学太差的我……
下次得好好补数论了

5 楼

iAkiak辛苦了,忙了一天。

我居然把break改成continue,惭愧,看代码短就没多测。  iAkiak实在太仁慈了,应该直接把我的程序毙掉的:)

这次的题目很不错,上手容易,照顾到了新人(第一题),仔细想又有很多地方可以优化。argentmoon后来在雪光风剑的讨论帖里提出了算法的改进,速度应该可以提高一个数量级。http://www.programfan.com/club/showbbs.asp?id=218153

6 楼

我的算法本质和NeverPE是一样的,而且我把
sum = (a1^0+a1^1+a1^2...a1^t1) * (a2^0+a2^1+a2^2...a2^t2) * .....  (1)
这个式子中的(a1^0+a1^1+a1^2...a1^t1)变成了(a1^(t1+1)-1)/(a1-1)
不明白为什么会错了。请明白的大人给解释一下,或找指出其中的错误。
先在此谢过。

7 楼

还有很大差距啊!

8 楼

[quote]我的算法本质和NeverPE是一样的,而且我把
sum = (a1^0+a1^1+a1^2...a1^t1) * (a2^0+a2^1+a2^2...a2^t2) * .....  (1)
这个式子中的(a1^0+a1^1+a1^2...a1^t1)变成了(a1^(t1+1)-1)/(a1-1)
不明白为什么会错了。请明白的大人给解释一下,或找指出其中的错误。
先在此谢过。[/quote]
你第一题不是就出问题了么

9 楼

这个测试我完全看不懂,郁闷

10 楼

这种算法太BT了,根本想不到.....

我来回复

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