热爱编程,热爱生活!

禁用chrome flash插件

windows下还好,linux下动不动就占用cpu 100% ,fuck

在chrome 的地址栏中输入 about:plugins 就可以看到那些插件了,直接禁止即可。

linux下可以用 top 命令查看各进程的 cpu 等资源的占用情况。

gcc的安装与版本切换

windows下的vs2012对c++11力度不够。最近把gcc4.7.3支持的c++11特性玩了一遍,没办法,只能升级到gcc4.8.1才能继续玩了。。

目前最新版是 gcc4.8.1
可以用PPA来安装,输入如下命令即可:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.8

安装好了后,如果以前安装了gcc版本的话,可以输入下面命令可以查看:
ls /usr/bin/gcc*

我的系统中显示:
/usr/bin/gcc /usr/bin/gcc-ar-4.7 /usr/bin/gcc-nm-4.8
/usr/bin/gcc-4.7 /usr/bin/gcc-ar-4.8 /usr/bin/gcc-ranlib-4.7
/usr/bin/gcc-4.8 /usr/bin/gcc-nm-4.7 /usr/bin/gcc-ranlib-4.8

现在我电脑上面安装了gcc-4.8 和 gcc-4.7 两个版本,用gcc -v 命令查看还是以前的 gcc-4.7.3 。
可以使用update-alternatives管理电脑上的GCC版本
sudo update-alternatives –install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
sudo update-alternatives –install /usr/bin/gcc gcc /usr/bin/gcc-4.7 40

这样在输入 gcc -v 查看就是 gcc-4.8.1 了

下面在gcc各版本间切换:
sudo update-alternatives –config gcc

有 2 个候选项可用于替换 gcc (提供 /usr/bin/gcc)。

选择 路径 优先级 状态
————————————————————
0 /usr/bin/gcc-4.8 50 自动模式
* 1 /usr/bin/gcc-4.7 40 手动模式
2 /usr/bin/gcc-4.8 50 手动模式

要维持当前值[*]请按回车键,或者键入选择的编号即可。

同样的方法可以安装 g++ 。
我是这样编译 cpp 程序的, g++ -std=c++11 test.cpp
所以有必要也使用最新版的 g++ 。

右值引用

左值和右值

一个区分左值和右值的方法是:看能不能对表达式取地址,如果能,则是左值,不能,则是右值。
左值是指表达式结束后依然存在的持久对象,右值是指表达式结束后就不再存在的临时对象。例如:a,b,++a是左值,a+b,a++是右值。

看个例子:
int &m = 1; 编译显示:错误: 用类型为‘int’的右值初始化类型为‘int&’的非常量引用无效

const int &m = 1; 编译通过,m是一个常量引用,引用到一个右值,但引用本身是一个持久对象(可以对其取地址),为左值。

常量左值,非常量左值,常量右值,非常量右值。

int a = 10; const int b = 10;

int &m = a 合法 , 绑定到非常量左值
int &m = a++ 非法, 非常量右值
int &m = ++a 合法, 非常量左值
int &m = b 非法 , 常量左值
int &m = 10 非法, 常量右值

非常量左值引用只能绑定到非常量左值,不能绑定到常量左值,非常量右值,常量右值。可以这样想,如果允许绑定到常量左值和常量右值,则非常量左值引用可以用于修改常量左值和常量右值,这明显违反了其常量的含义。
如果允许绑定到非常量右值,则会导致非常危险的情况,因为非常量右值是一个临时对象,非常量左值引用可能会使用一个已经被销毁了的临时对象。

常量左值引用可以绑定到所有类型的值。

可以看出,使用左值引用时,我们无法区别出绑定的是否是非常量右值的情况。
那么,为什么要对非常量右值进行区分呢,区分出来了又有什么好处呢?这就牵涉到C++中一个著名的性能问题——拷贝临时对象。

C++11中用 & 表示左值引用,用 && 表示右值引用:

参考这篇文章:
http://www.cnblogs.com/hujian/archive/2012/02/13/2348621.html

右值引用根据其修饰符的不同,也可以分为非常量右值引用和常量右值引用。

int n = 10;
const int a = 10;
int &&m = 10 合法,这里请参考上面那篇文章的评论
int &&m = n 非法,非常量左值
int &&m = a 非法,常量左值
int &&m = n++ 合法,非常量右值
int &&m = ++n 非法,非常量左值


非常量右值引用只能绑定到非常量右值,不能绑定到非常量左值、常量左值和常量右值。如果允许绑定到非常量左值,则可能会错误地窃取一个持久对象的数据,而这是非常危险的;如果允许绑定到常量左值和常量右值,则非常量右值引用可以用于修改常量左值和常量右值,这明显违反了其常量的含义。

常量右值引用可以绑定到非常量右值和常量右值,不能绑定到非常量左值和常量左值(理由同上)

本文大部分引用 http://www.cnblogs.com/hujian/archive/2012/02/13/2348621.html

强烈建议参考:
http://amazingjxq.com/2012/06/06/译详解c右值引用/

编译C++ 11

vs2012什么都不用管就可以编译。

linux下gcc编译器应该这样编译:
g++ -std=c++11 hello.cpp
g++ -std=gnu++11 hello.cpp

windows下 Dev-C++ 5.4.2 应该如下设置:
工具 -> 编译器选项 ,”在连接器命令行加入以下命令” 中默认的是 -static-libgcc
在这个后面再加上 -std=c++11 或 -std=gnu++11 即可。

C++ 11

C++ 11 FAQ
C++ 11 FAQ中文版
The GNU C++ Library

gdb调试

详见:http://blog.csdn.net/haoel/article/details/2879

man page里面函数后面的括号加数字什么意思?

所有的手册页都属于一个特定的领域,用一个字符来表示。

Linux下最通用的领域及其名称及说明如下:
领域 名称 说明

1 用户命令, 可由任何人启动的。

2 系统调用, 即由内核提供的函数。

3 例程, 即库函数。

4 设备, 即/dev目录下的特殊文件。

5 文件格式描述, 例如/etc/passwd。

6 游戏, 不用解释啦!

7 杂项, 例如宏命令包、惯例等。

8 系统管理员工具, 只能由root启动。

9 其他(Linux特定的), 用来存放内核例行程序的文档。

n 新文档, 可能要移到更适合的领域。

o 老文档, 可能会在一段期限内保留。

l 本地文档, 与本特定系统有关的。

例如:man ls就会有LS(1)

初玩linux

下面是腾讯游戏开发方向的岗位要求:
本科及以上学历。
对于创新及解决具有挑战性的问题充满激情。
具有良好的算法基础及系统分析能力。
前台熟悉Windows平台、2D图形、3D(引擎)技术、C/C++,网络、Flash、WEB、多种终端技术,后台熟悉Linux、UNIX操作系统、C/C++、网络知识、数据结构/算法、架构、数据库知识等。
同时你对绚烂的2D界面、3D光效、华丽的动作特效有痴迷,幻想速度与激情的冲动,梦想在网页上点击几下鼠标成就千古功名,追求在技术上挑战数万人一起游戏的后台,上千人的同屏显示……你完全有把握成为腾讯游戏开发团队的一员,用自己的代码创造一个快乐的虚拟世界。

python果然强大,而且易学,ubuntu的界面果然酷炫,在linux下工作高效的原因可能是桌面的右下角没有企鹅了 and 我不能杀四国军棋了,哈哈:)
这几天基本熟悉了pygame模块。。扩充一下知识面,玩玩linux好了,先拿着个下手:
Linux C编程一站式学习

初玩Pygame

5.12–5.24在中软打了两个星期酱油,用jsp做了管理系统的几个模块,,最bs学院组织的这种实习了,ca
还剩一个月放假,这个时间段好尴尬,不长不短,看看书差不多,做东西的话就算了。。。
刚搞完《windows核心编程》,又学了下python的基本语法,还把妹子坑上了android不归路,哎,哥也玩玩pygame去。。。
http://eyehere.net/2011/python-pygame-novice-professional-index/

k-d tree

最近在用 win32 + DirectX9.0 重写以前用 MFC+win32API 写过的坦克大战。。。

以前的碰撞检测用的是网格模型,,游戏的设计思想是一个二维数组map记录地图,然后坦克占 5*5 方格,子弹占 1*1 方格, 不同的物体的map的值不同,比如,坦克在(3,4)位置,子弹在(5,2)位置,那么 map[3][4] = 1, map[5][2] = 2 ….
那么碰撞就可以通过坐标对应的map值去判断,这样的话,每次物体运动就要立即更改map对应位置的值,但这样有一个很大的缺点就是随着游戏规模
的增大,碰撞检测的代码复杂度和时间复杂度会非常大,不利于功能的扩展,如果一定要这样,那有必要去看看设计模式了。

现在的碰撞检测用的是矩形检测模型,把每个物体可以抽象出一个矩形。
普通的做法是两两判断是否碰撞,复杂度 O(n^2),一般小地图还是足够了的,但像魔兽那种大地图就不行了。
用k-d tree 检测判断可以优化到 O(nlogn).

2D用四叉树,3D用八叉树,这两种都可以用 k-d tree解决。

关于游戏中的碰撞检测:
http://cheney-mydream.iteye.com/blog/1299214
http://blog.csdn.net/zhanxinhang/article/details/6706217

关于 k-d tree:
http://www.cnblogs.com/eyeszjwang/articles/2429382.html

下面用 hdu 4347 作为例子:
hdu 4347

题意: 给出 K 维空间的 N 个点,求距离某个点最近的 M 个点。

( 1 < = N < = 50000 , 1 < = K < = 5 , 1 < = T < = 10000, 1 < = M < = 10 ) . 输入要求: 输入非负整数 N 和 K. 然后输入 N 个 K 维空间的坐标点(n行,每行k个整数)。 然后输入 整数 T ,表示 T 次查询。 每次查询包含两行,第一行为 K 个整数(表示这个点的坐标,设为P) ,第二行为 M 。 输出离 点P 最近的 M 个点,要求按距离从小到大排序输出。(数据保证只有一个答案) 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstdio>
using namespace std;
 
const int MAXN = 500005;
const int MAXK = 5;
 
int N,K,index;   // N 表示 点数, K 表示维数
 
struct Point
{
	int x[MAXK];	// K 维坐标
	friend bool operator < (const Point& a,const Point& b)
	{
		return a.x[index] < b.x[index];
	}
 
}point[MAXN];
 
 
typedef pair<int,Point> PIP;	// first 表示 距离的平方
priority_queue<pip> ansQue;   // 保存 离点 p 最近的 M 个点
 
 
// 返回两点距离的平方
int GetDis2(const Point& a,const Point& b)
{
	int dis2 = 0;
	for(int i=0;i<k;++i)
		dis2 += (a.x[i]-b.x[i])*(a.x[i]-b.x[i]);
	return dis2;
}
 
// KD_TREE的算法不会改变 point[]
struct KD_TREE
{
	Point pt[MAXN<<2];
	int child[MAXN<<2];
 
	void build(int left,int right,int rt=1,int depth=0)
	{
		if(left > right)
			return ;
 
		child[rt] = right - left;
		child[rt<<1] = child[rt<<1 | 1] = -1;
		index = depth % K;	//
 
		int mid = (left+right)>>1;
 
		nth_element(point+left,point+mid,point+right+1);  // 超平面分割
 
		pt[rt] = point[mid];
 
		build(left,mid-1,rt<<1,depth+1);
		build(mid+1,right,rt<<1 | 1,depth+1);
	}
 
	void query(const Point& p,int M,int rt=1,int depth=0)
	{
		if(-1 == child[rt])
			return ;
 
		PIP pip(0,pt[rt]);
		pip.first = GetDis2(pt[rt],p);
 
		int dim = depth % K, x = rt<<1, y = rt<<1 | 1 ,flag = 0 ;
 
		if(p.x[dim] >= pt[rt].x[dim])
			swap(x,y);
		if(child[x] != -1)
			query(p,M,x,depth+1);
 
		if(ansQue.size() < M)
		{
			ansQue.push(pip);
			flag = 1;
		}
		else
		{
			if(pip.first < ansQue.top().first)
			{
				ansQue.pop();
				ansQue.push(pip);
			}
			if( (p.x[dim]-pt[rt].x[dim])*(p.x[dim]-pt[rt].x[dim]) < ansQue.top().first )
				flag = 1;
		}
		if(child[y] != -1 && flag)
			query(p,M,y,depth+1);
	}
 
}kd;
 
int main()
{
	while(scanf("%d%d",&N,&K) == 2)
	{
		for(int i=0;i<n;++i)	//读入 N 个 K 维坐标点
		{
			for(int j=0;j<k;++j)
				scanf("%d",&point[i].x[j]);
		}
 
		kd.build(0,N-1);	//建立 kd-tree
 
		int T,M;
		Point p;
 
		scanf("%d",&T);
		while(T--)
		{
			for(int i=0;i<k;++i)
				scanf("%d",&p.x[i]);
			scanf("%d",&M);
 
			kd.query(p,M);	 //查询 离点 p 最近的 M 个点
 
			printf("the closest %d points are:n",M);
 
			Point ans[15];
			for(int i=0; !ansQue.empty(); ++i)
			{
				ans[i] = ansQue.top().second;
				ansQue.pop();
			}
 
			for(int i=M-1; i>=0; --i)  // 按距离从小到大输出
			{
				for(int j=0;j<k-1;++j)
					printf("%d ",ans[i].x[j]);
				printf("%dn",ans[i].x[K-1]);
			}
		}
 
	}
 
    return 0;
}