给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。要求:空间复杂度O(1)

其实原理很简单,奇数和偶数必定成对的交换位置。

 

# values = [1, 3, 5, 7, 2, 4, 6, 9, 11, 8, 10]
values = [1, 2, 3, 4, 5, 6, 7, 8, 20, 19, 18, 17, 16]

# left:  odd
# right: even
def partition(values)
  low = 0
  high = values.size - 1
  while low < high
    if 0 == (values[low] % 2)
      while 1 != (values[high] % 2)
        high = high - 1
      end
      if high > low
        values[low], values[high] = values[high], values[low]
      end
    elsif
      low = low + 1
    end
  end
end

partition(values)
puts(values)

 

posted @ 2010-12-02 15:49 装甲熊猫 阅读(48) 评论(0) 编辑

http://projecteuler.net/index.php?section=problems&id=72

欧拉函数本身的计算并不困难,但是1到1,000,000,要想算得快的话就必须利用以下推论:

若(N%a==0 && (N/a)%a==0) 则有:Phi(N)=Phi(N/a)*a;

若(N%a==0 && (N/a)%a!=0) 则有:Phi(N)=Phi(N/a)*(a-1);

(这里a为质数)

有了这个推论,我们就可以用空间换时间来解决。代码写的不是很好,大概8秒不到能得到结果。这里使用筛法求1,000,000以内素数。

from math import sqrt

MAX_LIMIT = 1000000
R_MAX_LIMIT = sqrt(MAX_LIMIT)
prime_list = []
prime_mask = []    # start from 2 to 1,000,000
phi_cached = {}

def Phi(number):
    if number in phi_cached:
        return phi_cached[number]
    
    if 0 != prime_mask[number - 2]:
        phi_cached[number] = number - 1
        return phi_cached[number]
    else:
        root = sqrt(number)
        for i in range(0, len(prime_list)):
            p = prime_list[i]
            if p > root:
                break;
            if 0 == (number % p):
                minor = number // p
                if 0 == minor % p:
                    phi_cached[number] = Phi(minor) * p
                else:
                    phi_cached[number] = Phi(minor) * (p - 1)
                return phi_cached[number]
        
# build prime list/mask
for i in range(2, MAX_LIMIT + 1):
    prime_mask.append(i)

for i in range(0, len(prime_mask)):
    p = prime_mask[i]
    if p != 0:
        index = p * 2
        while index <= MAX_LIMIT:
            prime_mask[index - 2] = 0
            index += p

for i in range(0, len(prime_mask)):
    if prime_mask[i] > R_MAX_LIMIT:
        break
    if 0 != prime_mask[i]:
        prime_list.append(prime_mask[i])

sum = 0
for i in range(2, MAX_LIMIT + 1):
    sum += Phi(i)
print("sum = %d" % sum)

posted @ 2010-11-09 09:02 装甲熊猫 阅读(28) 评论(0) 编辑

http://projecteuler.net/index.php?section=problems&id=65

Python真是个好东西,再也不用为大数操心了。

e_list = [2]

def Add(number, up, down):
    return number * down + up, down

def CalcTemp(start, end):
    if (start + 1) == end:
        up, down = Add(e_list[start], 1, e_list[start + 1])
        return up, down
    else:
        up, down = CalcTemp(start + 1, end)
        up, down = down, up
        return Add(e_list[start], up, down)

def Resolve(end):
        up, down = CalcTemp(1, end)
        up, down = down, up
        return Add(e_list[0], up, down)

for i in range(1, 100):
    if 2 == (i % 3):
        e_list.append(2 * (i // 3 + 1))
    else:
        e_list.append(1)
        
up, down = Resolve(99)
print("up = %d\n" % up)
print("down = %d\n" % down)

sum = 0
while up > 0:
    sum += up % 10
    up //= 10
print("sum = %d\n" % sum)

posted @ 2010-11-03 09:25 装甲熊猫 阅读(27) 评论(0) 编辑
时间限制:
1000ms
内存限制:
65536kB
描述
计算a的b次方对9907取模的值。
输入
第一行有一个正整数T,表示有T组测试数据。
接下来T行,每行是一组测试数据,包含两个整数a和b。
其中T<=10000, 0 <=a,b < 2^31。
输出
有T行,依次输出每组数据的结果。
样例输入
3
1 2
2 3
3 4
样例输出
1
8
81

虽然a和b给出的范围很大,但自己先列下式子比划一下,其实题目还是非常简单的。

令c=9907,把a写成a=xc+y,那么(a^b)%c根据2项式展开就应该等于(y^b)%c。如果a比较大的话,就可以降解成一个比较小的值了。

但是如果b也巨大无比怎么办呢?任取一数A = Xc + Y; A^2 =(Xc)^2+2XYc+Y^2,这个数对c取2模就是Y^2也就是A%c。如果b是偶数,就先对a^(b/2)取模,再把结果相乘再取模。如果是奇数呢?那就把a^(b-1)的结果算出来,假设结果A=Xc+Y,再乘以a=xc+y,那么最终结果就是(Yy)%c。那么,现在就拜托递归了。

#include <stdio.h>

int calcMod(int a, int b, int c)
{
	int b1;
	int x;

	if (a >= c)
	{
		return calcMod(a % c, b, c);
	}

	if (a == 1)
	{
		return 1;
	}

	if (a == 0)
	{
		return 0;
	}

	if (b == 1)
	{
		return a;
	}

	if (b == 0)
	{
		return 1;
	}

	b1 = b / 2;
	x = calcMod(a, b1, c);
	if (1 == (b % 2))
	{
		return (x * x * (a % c)) % c;
	}
	else
	{
		return (x * x) % c;
	}
}

int main(void)
{
	int a = 17, b = 30;
	int c = 9907;

	printf("%d^%d mod %d = %d\n", a, b, c, calcMod(a, b, c));
}

 

posted @ 2010-05-25 21:49 装甲熊猫 阅读(31) 评论(0) 编辑

前段时间对测试代码的编译环境做了一些修改,在做free build的时候取消了_DEBUG/DEBUG的定义。最近跑test时出了一个以前从为出现过的错误,debug后发现if/else的工作不正常,在if已经判断为true后还是进入了else。想到某人数月前抱了一个编译环境的bug,难道这种小概率事件也降临到我头上。经过N小时反复研究代码,终于发现了问题的症结所在。

先看一下以下这段define(实际代码略复杂,此处做了简化):

#ifdef _DEBUG
    #define TRACE printf
#else
    #define TRACE if (0) printf
#endif

有问题吗?貌似OK,如果是free build就不执行printf。事实上在大多数情况下都没什么问题,但是再看看以下代码:

 if (1)
    TRACE("OK\n");
 else
    printf("Why?\n");

在Visual Studio中分别用DEBUG和RELEASE编译看看运行结果,是不是比较奇怪?

其时,在_DEBUG没有被define的情况下,宏展开后的代码是这样的:

if (1)

    if (0)

        printf("OK\n");

    else

        printf("Why\n");

因为TRACE后面跟不定参数,我们无法使用"#define TRACE ",考虑到尽可能减少对现有代码的影响,修改为"#define TRACE while (0) printf"。

 

以上代码绝非新手所为,即使是老鸟偶尔还是会阴沟里翻船^_^怪不得老大总是说我们的test当年free build没法跑,最后只跑chk build。

posted @ 2010-05-24 21:58 装甲熊猫 阅读(18) 评论(0) 编辑
摘要: Categories以前从来没看到类似的概念,可能和微软的COM比较相似,仅仅是可能。Categories要解决什么问题呢?当然是继承和扩展现有类,但是基于OC自身的特性,比如我们想要扩展NSString的功能,但NSString是一个class cluster,所以我们不能直接继承。就需要通过某种方法解决。比如我们现在需要一个方法把字符串的长度打包成一个NSNumber返回。ExtendedSt...阅读全文
posted @ 2010-05-16 14:57 装甲熊猫 阅读(38) 评论(0)  编辑
摘要: OC的内存管理:虽然没有所谓的析构函数,但当对象的引用计数为0时,OC会自动调用dealloc message(关于message,以后再说),而这个dealloc是我们可以重载的。对象的retain,release和retainCount方法顾名思义。特别指出一下retain,类似于IUnknown结构的QueryInterface,不但返回一个指针,内部还AddRef了一把。Cocoa内存管理...阅读全文
posted @ 2010-05-12 21:43 装甲熊猫 阅读(144) 评论(0)  编辑
摘要: 成员函数前的修饰符:+表示static成员函数,-表示普通成员函数。类的私有成员函数可以不写在声明中,直接写在实现中就可以了。如何调用私有成员函数呢?在OC中用self表示this指针,super表示上级指针。参考如下代码:@implementation Shape- (NSString*) description{ return @"I'm a shape";}- (void) DrawPriv...阅读全文
posted @ 2010-05-04 15:13 装甲熊猫 阅读(427) 评论(0)  编辑
摘要: OC用import来include头文件,比如#import <Foundation/Foundation.h>。LSLog(@"Hello, Objective-C!")用于在console上输出信息,类似于printf,不过自动加了‘\n'。字符串前面加@表示被转换成NSString。NSString提供的一些额外功能: - Tell you its length - ...阅读全文
posted @ 2010-04-24 16:39 装甲熊猫 阅读(81) 评论(0)  编辑
摘要: http://projecteuler.net/index.php?section=problems&id=60刚看到题目有些吓人,5个质数,任选2个拼起来还是指数,一开始摸不到边,那就硬来吧。首先做个乐观的假设,最大的那个质数小于10000。这也行?只能凑合了,提交答案后看了一下,也没有什么特别好的算法。既然我们假设最大的那个质数小于1000,那就把小于10000的质数生成一个表,然后5...阅读全文
posted @ 2010-02-21 22:50 装甲熊猫 阅读(54) 评论(0) 编辑