进阶之路

首页 新随笔 管理
1. 约瑟夫(环)问题。 

见于:http://www.cnblogs.com/liyangguang1988/p/3620007.html

 (数学推理部分开始)

 

 2. 不用任何中间变量交换两个变量 a 和 b 的值。

 方法1:                                                      方法2:(适用整型)

 a = a + b;                                                  a = a ^ b;

 b = a - b;                                                   b = a ^ b;

 a = a - b;                                                   a = a ^ b;

 

3. 不用加减乘除求两个整数的和。

求整数 a,b 的和:

步骤A:令 s = a ^ b,将所有位相加,有进位处置 0 (相当于舍弃进位相加)。—>步骤B

步骤B:  令 d = a & b,则求出所有进位,

若 d == 0,则无进位,返回 s;

若 d != 0,则返回(d << 1) + s 。即将所有进位左移一位,将问题化成 (d << 1) 与 s 求和的问题。可令 a = d << 1,b = s,—>步骤A

例如:a = 5,b = 13 时:计算机内表示为,a =0101,b = 1101,

步骤A:  s = a ^ b = (0101) ^ (1101) = 0 1000. —>步骤B

步骤B:  d = a & b = (0101) & (1101) = 0101。 1,3 位有进位,d != 0,于是 a = s = 1000,b = d << 1 = 0101,—>步骤A2

步骤A2: s = a ^ b = (1000) ^ (0101) = 1101。—>步骤B2

步骤B2: d = a & b = (1000) & (0101) = 0000。d == 0 ,无进位,返回 s = 1101. 即 13 

注:负数在计算机中用补码表示,但是负数之间也满足这种求和方法。正数与负数之间求和也适用于此方法)

代码:

/********** 注:超出边界时溢出 *************/
int add(int num1, int num2)
{
	int sum = num1 ^ num2;
	while(num1 & num2)
	{
		num1 = (num1 & num2) << 1;
		num2 = sum;
		sum = num1 ^ num2;
	}
	return sum;
}

int main()
{
	std::cout << add(0x7fffffff >> 1, (0x7fffffff >> 1)+1) << std::endl;
	return 0;
}

 结果:

 

4. 不用乘、除、取余运算实现两个 int 值相除。

code:

class Solution {
public:
	int divide(int dividend, int divisor) {
		if(divisor == 0) return INT_MAX;
		bool signal = false;
		bool overflow = false;
		if(dividend < 0) {
			signal = !signal;
			if(dividend == INT_MIN) { overflow = true; dividend++; }
			dividend *= -1;
		} 
		if(divisor < 0) {
			signal = !signal;
			if(divisor == INT_MIN) {
				if(overflow) return 1;
				else return 0;
			}
			divisor *= -1;
		}
		int result = 0;
		while(dividend >= divisor) {
			int x(divisor);
			int r(1);
			while(dividend-x >= x) {
				x += x;
				r += r;
			}
			dividend -= x;
			result += r;
		}
		if(overflow && dividend +1 == divisor) result++;
		return signal ? (-result) : result;
	}
};

 

 

 5. 找数组中单数问题

 见于:http://www.cnblogs.com/liyangguang1988/p/3622257.html

 

  6. ACM: 今天是星期一,再过 1^1+2^2+3^3+4^4+…+N^N天后是星期几?( 0 =< N <= 10亿)时间限制:2秒

原题:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5272      

  base: 0  1  2  3  4  5  6   

       0  0   

      1  1    

      2  1  2  4  1   

  3  1  3  2  6  4  5  1

   1  4  2  1

  5  1  5  4  6  2  3  1

  6  1  6  1

 code:

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 string day[] = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
 5 int base[7][7];
 6 int circle[7] = {1, 1, 3, 6, 3, 6, 2};
 7 
 8 inline void init()
 9 {
10     for(int i = 1; i < 7; ++i)
11     {
12         int step = 1;
13         base[i][0] = step % 7;
14         for(int j = 1; j < 7; ++j)
15         {
16             step *= i;
17             base[i][j] = step % 7;
18         }
19     }
20 }
21 
22 int main()
23 {
24     int N;
25     init();
26     while(cin >> N)
27     {
28         int sum = 0;
29         N = N % 294;
30         while(N)
31         {
32             int t1 = N % 7;
33             int t2 = N % circle[t1];
34             sum = (sum + base[t1][t2]) % 7;
35             --N;
36         }
37         cout << (day[sum]) << endl;
38     }
39     return 0;
40 }
View Code

 

 附:n x n 的正方形中,有多少长方形?  答案: C(n+1, 2)2-n(n+1)(2n+1)/6 = n(3n+2)(n2-1)/12 . 

 

 

posted on 2014-03-24 00:52  进阶之路  阅读(1187)  评论(0编辑  收藏  举报