Wednesday, October 10, 2007

天平称球问题的解法

发现这个问题在网上不停地被问,给个解答。
First give several lemmas here:
1. If we know the broken ball is heavy or light, we can find the broken ball from 3^t balls in t steps. And we cannot find it from over 3^t balls in t steps.
2. We can find the broken ball from less that (3^t -1)/2 balls in t steps, and know whether it’s heavy or light. And we cannot determine the broken ball is heavy or light for (3^t -1)/2 or more balls in t steps.
3. We can find the broken ball from (3^t +1)/2 balls with another good ball, however may not know whether the ball is heavy or light.
4. We can find the broken ball from (3^t -1)/2 balls in t steps, however, may not know whether it’s heavy or light.
5. Given a good ball, we can find the broken ball from (3^t -1)/2 balls in t steps, and know whether it’s heavy or light.

Proof:
1) Lemma 1 is obvious, pass it.
2) We then try to prove first part of lemma 2. The following proof only apply to t >= 3; for t = 1, 2, you can verify it easily.
We pick (3^t -3)/2 as example, if we can make for it, obvious we can make for numbers less than it. We first split the balls into three piles, exactly (3^(t-1) -1)/2 balls for each pile. We name them A, B and C. Then, we put A and B in the scales, three results are possible here:
a) Balance. We need determine the broken ball from C in t-1 steps. This is what lemma 5 tells.
b) A is heavy. We now know C is already good balls. We then split A to A1 and A2, B to B1 and B2. A1 and B1 with size, A2 and B2 with size (3^(t-2) -1)/2. We then put A1 and B2 in left side of scales, A2 and other 3^(t-2) good balls from C in right side. Three results here also:
 Balance. We know bad ball is in B1, and it’s light. From lemma 1, we can find it out in t-2 steps
 Left is heavy. We know bad ball is in A1, and it’s heavy. From lemma 1, we can find it out in t-2 steps.
 Right is heavy, we know that bad ball is a heavy ball in A2 or a light ball in B2. Notice A2 and B2 both have (3^(t-2) -1)/2 balls, so we got a recursive situation here. And for t=3, the most simple situation, it’s apparently true. Done.
c) A is light, similar with b). Done.
3) Now come to second part of lemma 2. From information theory, we can easy know we cannot find the broken ball from more than (3^t -1)/2 balls in t steps. We now need prove it also impossible to find the broken ball in t steps for exact (3^t -1)/2 balls. If we can, think we about the decision tree, we must average divide among the three child nodes (balance, left heavy and right heavy) for each node, it impossible since (3^t -1)/2 is not a multiplier of 3.
4) We then prove lemma 3. For t = 1, it’s obvious. For t > 1, we divide the balls to three piles, respectively, A with (3^t -1)/2 balls, B with (3^(t-1) +1)/2 balls and C with (3^(t-1) +1)/2 balls. We first put A and the good ball, namely G in left, and B in right. If balance, bad ball in C, and we get a recursive situation. If not balance, suppose left heavy. We then divide A to A1 and A2, B to B1 and B2, A1 and B1 have 3^(t-2) balls, A2 with (3^(t-2) -1)/2 balls, B2 with (3^(t-2) +1)/2 balls. We put A1 and B2 in left, A2 and 3^(t-2) +1 good balls in right. There are tree situations here:
a) Left heavy, then bad ball in A1 and heavy, from lemma 1 we can find it in t-2 steps.
b) Balance, then bad ball in B1 and light, from lemma 1 we can find it in t-2 steps.
c) Right heavy, bad balls in A2 or B2. We get a recursive situation here. Consider the simplest situation, A have 1 ball(named 1) and B have 2 ball(named 2 and 3). We put 1 and 2 in left, and another two good balls in right:
i. balance, we know 3 is the bad ball, and light
ii. left heavy, 1 is the bad ball, and heavy
iii. right heavy, 2 is the bad ball and light
The situation when right is heavy is similar.
5) Now to prove lemma 4. We divide the (3^t -1)/2 balls into three piles, respectively, A and B with (3^(t-1) -1)/2 balls, C with (3^(t-1) +1)/2 balls. Then we put A and B in the scale. If not balance, from 2) we know we can find the bad ball out. If balance, from lemma 3 we know we can find the bad ball, however, may not know whether it’s heavy or light.
6) At the end, we come to lemma 4. We divide the balls into A with (3^t -1)/2 balls, B with (3^(t-1) +1)/2 balls and C with (3^t -1)/2 balls. And put A and the good ball in left, B in right:
a) Balance, bad ball in C, we get a recursive situation here. And for t = 1, it apparently right.
b) Not balance, we get the exact same situation as in 4).

这是代码:
#include
#include
#include
using namespace std;

#include

DEFINE_bool(random, true, "");
DEFINE_int32(count, 13, "");
DEFINE_bool(has_good, false, "");
DEFINE_bool(is_heavy, false, "");
DEFINE_bool(is_light, false, "");

unsigned int three_power[20];

enum SCALE_STATUS {
SCALE_INVLIAD_STATUS = -1,
SCALE_LEFT_HEAVY = 0,
SCALE_RIGHT_HEAVY = 1,
SCALE_BALANCE = 2,
};

SCALE_STATUS GetScaleStatus(bool no_balance) {
static size_t count = 0;
cout << "The " << ++count;
switch (count % 10) {
case 1:
cout << "st test:\n";
break;
case 2:
cout << "nd test:\n";
break;
case 3:
cout << "rd test:\n";
break;
default:
cout << "th test:\n";
break;
}
SCALE_STATUS status = SCALE_INVLIAD_STATUS;

if (FLAGS_random) {
if (no_balance) {
status = static_cast(rand() % 2);
} else {
status = static_cast(rand() % 3);
}
} else {
do {
if (no_balance) {
cout << "Input scale status(L or R): ";
} else {
cout << "Input scale status(B, L or R): ";
}
char ch = '\0';
cin >> ch;
if (!no_balance && (ch == 'B' || ch == 'b')) {
status = SCALE_BALANCE;
} else if (ch == 'L' || ch == 'l') {
status = SCALE_LEFT_HEAVY;
} else if (ch == 'R' || ch == 'r') {
status = SCALE_RIGHT_HEAVY;
}
} while (status == SCALE_INVLIAD_STATUS);
}
return status;
}

void FindBadBallKnowHeavyOrLight(unsigned int count, int start_number,
bool heavy) {
assert(count > 0);
if (count == 3) {
cout << "\nPut " << start_number << " in left and "
<< start_number + 1 << " in right:\n";
SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is " << start_number + 2 << " and is ";
if (heavy) {
cout << "heavy.\n";
} else {
cout << "light.\n";
}
} else if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. ";
if (heavy) {
cout << "Bad ball is " << start_number << " and is heavy.\n";
} else {
cout << "Bad ball is " << start_number + 1 << " and is light.\n";
}
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight heavy. ";
if (heavy) {
cout << "Bad ball is " << start_number + 1 << " and is heavy.\n";
} else {
cout << "Bad ball is " << start_number << " and is light.\n";
}
}
return;
} else if (count == 2) {
cout << "\nPut " << start_number << " in left and "
<< start_number + 1 << " in right:\n";
SCALE_STATUS status = GetScaleStatus(true);
if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. ";
if (heavy) {
cout << "Bad ball is " << start_number << " and is heavy.\n";
} else {
cout << "Bad ball is " << start_number + 1 << " and is light.\n";
}
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight heavy. ";
if (heavy) {
cout << "Bad ball is " << start_number + 1 << " and is heavy.\n";
} else {
cout << "Bad ball is " << start_number << " and is light.\n";
}
}
return;
} else if (count == 1) {
cout << "\tBad ball is " << start_number << " and is ";
if (heavy) {
cout << "heavy.\n";
} else {
cout << "light.\n";
}
}

cout << "\nDivide the " << count << " balls into 3 piles:\n";
cout << "\tA of";
int next_count = (count - count / 3) / 2;
int i = 0;
for (; i < next_count; ++i) {
cout << " " << start_number + i;
}
cout << "\n\tB of";
for (; i < next_count * 2; ++i) {
cout << " " << start_number + i;
}
cout << "\n\tC of";
for (; i < count; ++i) {
cout << " " << start_number + i;
}
cout << "\nThen put A in left and B in right:\n";

SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is ";
start_number += next_count * 2;
count -= next_count * 2;
if (count == 1) {
cout << start_number;
} else {
cout << "in C";
}
} else {
if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft Heavy. Bad ball is ";
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight Heavy. Bad balk is ";
}
count = next_count;
if (status == SCALE_LEFT_HEAVY && heavy ||
status == SCALE_RIGHT_HEAVY && !heavy) {
if (count == 1) {
cout << start_number;
} else {
cout << "in A";
}
} else {
start_number += count;
if (count == 1) {
cout << start_number;
} else {
cout << "in B";
}
}
}
if (heavy) {
cout << " and is heavy.\n";
} else {
cout << " and is light.\n";
}

if (count > 1) {
FindBadBallKnowHeavyOrLight(count, start_number, heavy);
}
}

void FindBadBallInternal1(unsigned int count, int start1, int start2,
bool left_heavy) {
assert(count > 0);
if (count == 1) {
cout << "\nPut " << start1 << " in left and a good ball in right:";
SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is " << start2 << " and is ";
if (left_heavy) {
cout << "light.\n";
} else {
cout << "heavy.\n";
}
} else {
if (left_heavy) {
cout << "\tLeft heavy. Bad ball is " << start1 << " and is light.\n";
} else {
cout << "\tRight heavy. Bad ball is " << start1 << " and is heavy.\n";
}
}
return;
} else if (count == 2) {
cout << "\nPut " << start1 << " in left and " << start1 + 1 << " in right:";
SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance.\n";
status = GetScaleStatus(true);
if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. ";
if (left_heavy) {
cout << "Bad ball is " << start2 + 1 << " and is light.\n";
} else {
cout << "Bad ball is " << start2 << " and is heavy.\n";
}
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tLeft heavy. ";
if (left_heavy) {
cout << "Bad ball is " << start2 << " and is light.\n";
} else {
cout << "Bad ball is " << start2 + 1 << " and is heavy.\n";
}
}
} else if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. ";
if (left_heavy) {
cout << "Bad ball is " << start1 << " and is heavy.\n";
} else {
cout << "Bad ball is " << start1 + 1 << " and is light.\n";
}
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight heavy. ";
if (left_heavy) {
cout << "Bad ball is " << start1 + 1 << " and is heavy.\n";
} else {
cout << "Bad ball is " << start1 << " and is light.\n";
}
}
return;
}
int next_count = count / 3;
cout << "\nDivide A into A1 of";
int i = 0;
for (; i < count - next_count; ++i) {
cout << " " << start1 + i;
}
cout << " and A2 of";
for (; i < count; ++i) {
cout << " " << start1 + i;
}
cout << "\nDivide B into B1 of";
for (i = 0; i < count - next_count; ++i) {
cout << " " << start2 + i;
}
cout << " and B2 of";
for (; i < count; ++i) {
cout << " " << start2 + i;
}
cout << "\nThen put A1 and B2 in Left, put A2 and "
<< count - next_count << " good balls in right:\n";

SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is in B1 and is ";
if (left_heavy) {
cout << "light.\n";
FindBadBallKnowHeavyOrLight(count - next_count, start2, false);
} else {
cout << "heavy.\n";
FindBadBallKnowHeavyOrLight(count - next_count, start2, true);
}
} else if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. Bad ball is in A1 and is ";
if (left_heavy) {
cout << "heavy.\n";
FindBadBallKnowHeavyOrLight(count - next_count, start1, true);
} else {
cout << "light.\n";
FindBadBallKnowHeavyOrLight(count - next_count, start1, false);
}
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight heavy. Bad ball is in ";
if (left_heavy) {
cout << "A2(heavy) or B2(light). ";
} else {
cout << "A2(light) or B2(heavy). ";
}
cout << "\nNow assume A2 as A and B2 as B.\n";
FindBadBallInternal1(next_count, start1 + count - next_count,
start2 + count - next_count, left_heavy);
}
}

void FindBadBallInternal2(unsigned int count, int start1, int start2,
bool left_heavy) {
assert(count > 1);
if (count == 2) {
cout << "\n\nPut " << start2 << " in left and "
<< start2 + 1 << " in right:\n";
SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is " << start1 << " and is ";
if (left_heavy) {
cout << "heavy.\n";
} else {
cout << "light.\n";
}
} else if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. Bad ball is ";
if (left_heavy) {
cout << start2 + 1 << " and is light.\n";
} else {
cout << start2 << " and is heavy.\n";
}
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight heavy. Bad ball is ";
if (left_heavy) {
cout << start2 << " and is light.\n";
} else {
cout << start2 + 1 << " and is heavy.\n";
}
}
return;
}
int next_count = count / 3 + 1;
cout << "\nDivide A into A1 of";
int i = 0;
for (; i < count - next_count; ++i) {
cout << " " << start1 + i;
}
cout << " and A2 of";
for (; i < count - 1; ++i) {
cout << " " << start1 + i;
}
cout << "\nDivide B into B1 of";
for (i = 0; i < count - next_count; ++i) {
cout << " " << start2 + i;
}
cout << " and B2 of";
for (; i < count; ++i) {
cout << " " << start2 + i;
}
cout << "\nPut A1 and B2 in Left, put A2 and "
<< count - next_count + 1 << " good balls in right:\n";

SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is in B1 and is ";
if (left_heavy) {
cout << "light.\n";
FindBadBallKnowHeavyOrLight(count - next_count, start2, false);
} else {
cout << "heavy.\n";
FindBadBallKnowHeavyOrLight(count - next_count, start2, true);
}
} else if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. Bad ball is in A1 and is ";
if (left_heavy) {
cout << "heavy.\n";
FindBadBallKnowHeavyOrLight(count - next_count, start1, true);
} else {
cout << "left.\n";
FindBadBallKnowHeavyOrLight(count - next_count, start1, false);
}
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight heavy. Bad ball is in ";
if (left_heavy) {
cout << "A2(heavy) or B2(light). ";
} else {
cout << "A2(light) or B2(heavy). ";
}
cout << "\nNow assume A2 as A and B2 as B.\n";
FindBadBallInternal2(next_count, start1 + count - next_count,
start2 + count - next_count, left_heavy);
}
}

void FindBadBallWithGood(unsigned int count, int start_number) {
assert(count > 0);
if (count == 3) {
cout << "\nPut " << start_number << " in left and "
<< start_number + 1 << " in right:\n";
SCALE_STATUS status1 = GetScaleStatus(false);
if (status1 == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is " << start_number + 2 << ".\n";
cout << "\nPut " << start_number + 2
<< " in left and a good ball in right:\n";
SCALE_STATUS status2 = GetScaleStatus(true);
if (status2 == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. Bad ball is " << start_number + 2
<< " and is heavy.\n";
} else if (status2 == SCALE_RIGHT_HEAVY) {
cout << "\tRight heavy. Bad ball is " << start_number + 2
<< " and is light.\n";
} else {
assert(false);
}
} else {
if (status1 == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy.\n";
} else if (status1 == SCALE_RIGHT_HEAVY) {
cout << "\tRight heavy.\n";
} else {
assert(false);
}
cout << "\nPut " << start_number
<< " in left and a good ball in right:\n";
SCALE_STATUS status2 = GetScaleStatus(false);
if (status2 == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is " << start_number + 1 << " and is ";
if (status1 == SCALE_LEFT_HEAVY) {
cout << "light.\n";
} else {
cout << "heavy.\n";
}
} else {
status2 = status1;
if (status2 == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. Bad ball is " << start_number
<< " and is heavy.\n";
} else {
cout << "\tRight heavy. Bad ball is " << start_number
<< " and is light.\n";
}
}
}
return;
} else if (count == 2) {
cout << "\nPut " << start_number << " in left and "
<< start_number + 1 << " in right:\n";
SCALE_STATUS status1 = GetScaleStatus(true);
if (status1 == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy.\n";
} else {
assert(status1 == SCALE_RIGHT_HEAVY);
cout << "\tRight heavy.\n";
}
cout << "\nPut " << start_number << " in left and a good ball in right:\n";
SCALE_STATUS status2 = GetScaleStatus(false);
if (status2 == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is " << start_number + 1 << " and is ";
if (status1 == SCALE_LEFT_HEAVY) {
cout << "light.\n";
} else {
cout << "heavy.\n";
}
} else {
status2 = status1;
if (status2 == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy. Bad ball is " << start_number
<< " and is heavy.\n";
} else {
cout << "\tRight heavy. Bad ball is " << start_number
<< " and is light.\n";
}
}
return;
} else if (count == 1) {
cout << "\nPut " << start_number << " in left and a good ball in right:\n";
SCALE_STATUS status = GetScaleStatus(true);
if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft heavy.";
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight heavy.";
}
cout << " Bad ball is " << start_number << " and is ";
if (status == SCALE_LEFT_HEAVY) {
cout << "heavy.\n";
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "light.\n";
}
return;
}

int next_count = count / 3 + 1;

cout << "\nDivide the " << count << " balls into 3 piles:\n";
cout << "\tA of";
int i = 0;
for (; i < next_count - 1; ++i) {
cout << " " << start_number + i;
}
cout << "\n\tB of";
for (; i < next_count * 2 - 1; ++i) {
cout << " " << start_number + i;
}
cout << "\n\tC of";
for (; i < count; ++i) {
cout << " " << start_number + i;
}
cout << "\nThen put A and a good ball in left and B in right:\n";

SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is in C.\n";
FindBadBallWithGood(count - next_count * 2 + 1,
start_number + next_count * 2 - 1);
} else {
if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft Heavy. Bad ball is in A(heavy) or B(light)\n";
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight Heavy. Bad ball is in A(light) or B(heavy)\n";
}
FindBadBallInternal2(next_count, start_number,
start_number + next_count - 1,
(status == SCALE_LEFT_HEAVY));
}
}

void FindBadBallNormal(unsigned int count, int start_number) {
assert(count > 2);
int next_count = (count - count / 3) / 2;
cout << "\nDivide the " << count << " balls into 3 piles:\n";
cout << "\tA of";
int i = 0;
for (; i < next_count; ++i) {
cout << " " << start_number + i;
}
cout << "\n\tB of";
for (; i < next_count * 2; ++i) {
cout << " " << start_number + i;
}
cout << "\n\tC of";
for (; i < count; ++i) {
cout << " " << start_number + i;
}
cout << "\nThen put A in left and B in right:\n";

SCALE_STATUS status = GetScaleStatus(false);
if (status == SCALE_BALANCE) {
cout << "\tBalance. Bad ball is in pile C.\n";
FindBadBallWithGood(count - 2 * next_count, start_number + next_count * 2);
} else {
if (status == SCALE_LEFT_HEAVY) {
cout << "\tLeft Heavy. Bad ball is in A(heavy) or B(light)\n";
} else {
assert(status == SCALE_RIGHT_HEAVY);
cout << "\tRight Heavy. Bad ball is in A(light) or B(heavy)\n";
}
FindBadBallInternal1(next_count, start_number, start_number + next_count,
(status == SCALE_LEFT_HEAVY));
}
}

bool FindBadBall(unsigned int count) {
if (FLAGS_is_heavy || FLAGS_is_light) {
if (FLAGS_count > three_power[19]) {
cout << "Please input a valid number!\n";
return false;
}
int i = 0;
for (; i < sizeof(three_power) / sizeof(three_power[0]); ++i) {
if (FLAGS_count <= three_power[i]) break;
}
cout << "I can find the bad ball in at most " << i << " steps!\n";
FindBadBallKnowHeavyOrLight(FLAGS_count, 1, FLAGS_is_heavy);
} else if (!FLAGS_has_good) {
if (FLAGS_count < 3 || FLAGS_count >= (three_power[19] - 1) / 2) {
cout << "Please input a valid number!\n";
return false;
}
int i = 0;
for (; i < sizeof(three_power) / sizeof(three_power[0]); ++i) {
if (FLAGS_count < (three_power[i] - 1) / 2) break;
}
cout << "I can find the bad ball in at most " << i << " steps!\n";
FindBadBallNormal(FLAGS_count, 1);
} else {
if (FLAGS_count > (three_power[19] - 1) / 2) {
cout << "Please input a valid number!\n";
return false;
}
int i = 0;
for (; i < sizeof(three_power) / sizeof(three_power[0]); ++i) {
if (FLAGS_count <= (three_power[i] - 1) / 2) break;
}
cout << "I can find the bad ball in at most " << i << " steps!\n";
FindBadBallWithGood(FLAGS_count, 1);
}
return true;
}

int main(int argc, char** argv) {
if (!InitFlags(argc, argv)) {
cout << Usage(argv[0]) << endl;
return -1;
}
if (FLAGS_count < 1) {
cout << "Please input a valid number!\n";
return -1;
}
unsigned int current = 1;
for (int t = 0; t < sizeof(three_power) / sizeof(three_power[0]); ++t) {
three_power[t] = current;
current *= 3;
}

if (FLAGS_random) {
srand(time(NULL));
}

FindBadBall(FLAGS_count);

return 0;
}

Thursday, August 23, 2007

技术无用论

早上女朋友发了个网上的“给年轻工程师的十大忠告”,全文如下:

  <1>好好规划自己的路,不要跟着感觉走!根据个人的理想决策安排,绝大部分人并不指望成为什么院士或教授,而是希望活得滋润一些,爽一些。那么,就需要慎重安排自己的轨迹。从哪个行业入手,逐渐对该行业深入了解,不要频繁跳槽,特别是不要为了一点工资而转移阵地,从长远看,这点钱根本不算什么,当你对一个行业有那么几年的体会,以后钱根本不是问题。频繁地动荡不是上策,最后你对哪个行业都没有摸透,永远是新手!
  <2>可以做技术,切不可沉湎于技术。千万不可一门心思钻研技术!给自己很大压力,如果你的心思全部放在这上面,那么注定你将成为孔乙己一类的人物!适可而止为之,因为技术只不过是你今后前途的支柱之一,而且还不是最大的支柱,除非你只愿意到老还是个工程师!
  <3>不要去做技术高手,只去做综合素质高手!在企业里混,我们时常瞧不起某人,说他“什么都不懂,凭啥拿那么多钱,凭啥升官!”这是普遍的典型的工程师的迂腐之言。8051很牛吗?人家能上去必然有他的本事,而且是你没有的本事。你想想,老板搞经营那么多年,难道见识不如你这个新兵?人家或许善于管理,善于领会老板意图,善于部门协调等等。因此务必培养自己多方面的能力,包括管理,亲和力,察言观色能力,攻关能力等,要成为综合素质的高手,则前途无量,否则只能躲在角落看示波器!技术以外的技能才是更重要的本事!!从古到今,美国日本,一律如此!
  <4>多交社会三教九流的朋友!不要只和工程师交往,认为有共同语言,其实更重要的是和其他类人物交往,如果你希望有朝一日当老板或高层管理,那么你整日面对的就是这些人。了解他们的经历,思维习惯,爱好,学习他们处理问题的模式,了解社会各个角落的现象和问题,这是以后发展的巨大的本钱,没有这些以后就会笨手笨脚,跌跌撞撞,遇到重重困难,交不少学费,成功的概率大大降低!
  <5>知识涉猎不一定专,但一定要广!多看看其他方面的书,金融,财会,进出口,税务,法律等等,为以后做一些积累,以后的用处会更大!会少交许多学费!!
  <6>抓住时机向技术管理或市场销售方面的转变!要想有前途就不能一直搞开发,适当时候要转变为管理或销售,前途会更大,以前搞技术也没有白搞,以后还用得着。搞管理可以培养自己的领导能力,搞销售可以培养自己的市场概念和思维,同时为自己以后发展积累庞大的人脉!应该说这才是前途的真正支柱!!!
  <7>逐渐克服自己的心里弱点和性格缺陷!多疑,敏感,天真(贬义,并不可爱),犹豫不决,胆怯,多虑,脸皮太薄,心不够黑,教条式思维。。。这些工程师普遍存在的性格弱点必须改变!很难吗?只在床上想一想当然不可能,去帮朋友守一个月地摊,包准有效果,去实践,而不要只想!不克服这些缺点,一切不可能,甚至连项目经理都当不好--尽管你可能技术不错!
  <8>工作的同时要为以后做准备!建立自己的工作环境!及早为自己配置一个工作环境,装备电脑,示波器(可以买个二手的),仿真器,编程器等,业余可以接点活,一方面接触市场,培养市场感觉,同时也积累资金,更重要的是准备自己的产品,咱搞技术的没有钱,只有技术,技术的代表不是学历和证书,而是产品,拿出象样的产品,就可技术转让或与人合作搞企业!先把东西准备好,等待机会,否则,有了机会也抓不住!
  <9>要学会善于推销自己!不仅要能干,还要能说,能写,善于利用一切机会推销自己,树立自己的品牌形象,很必要!要创造条件让别人了解自己,不然老板怎么知道你能干?外面的投资人怎么相信你?提早把自己推销出去,机会自然会来找你!搞个个人主页是个好注意!!特别是培养自己在行业的名气,有了名气,高薪机会自不在话下,更重要的是有合作的机会...
  <10>该出手时便出手!永远不可能有100%把握!!!条件差不多就要大胆去干,去闯出自己的事业,不要犹豫,不要彷徨,干了不一定成功,但至少为下一次冲击积累了经验,不干永远没出息,而且要干成必然要经历失败。不经历风雨,怎么见彩虹,没有人能随随便便成功!

Tuesday, July 3, 2007

刘若英:为爱痴狂


我从春天走来
你在秋天说要分开
说好不为你忧伤
但心情怎会无恙
为何总是这样
在我心中深藏着你
想要问你想不想
陪我到地老天荒
如果爱情这样忧伤
为何不让我分享
日夜都问你也不回答
怎么你会变这样
想要问问你敢不敢
像你说过那样的爱我
想要问问你敢不敢
像我这样为爱痴狂
像我这样为爱痴狂
到底你会怎么想

         歌词一篇,昨日一时莫名悲伤,想起日后或会有此时刻;然峰回路转,破涕为笑仅是片刻之间。写下此篇以记之。

Friday, June 15, 2007

“不要比女人还罗嗦”

下午一个女同事如是说。

Sunday, June 10, 2007

功名泪

          周日早上起得迟,不想晚上难以入睡;躺在床上胡乱写了首小诗,平仄不对,词句不通,聊博一笑罢了。
真情难再少不知,欲问功名马蹄急。

十年征战万户侯,夜半蹒跚却忆昔。

Tuesday, June 5, 2007

大整数运算库(v1)

         这两天整理了一下以前写过的一个大整数运算库,主要是接口更友好些。以前写的那个主要运算是用汇编写的,这次全部改用C++实现了。目前只在VC8上编译过,相信在其它环境下也应该没什么问题。这是版本1,只实现了基本的算术运算,还没有以前实现过的模运算和一些基本的数论运算。同时写了一个unit test。文件链接:
http://yijinliu.googlepages.com/biginteger.h
http://yijinliu.googlepages.com/biginteger_unittest.cc
(如果下载不了,请找个能绕过盾的工具)

Thursday, May 31, 2007

凤凰卫视的报道视频

http://www.youtube.com/watch?v=s_NlEgdHlL4
Also Here:
http://yijinliu.googlepages.com/PX.flv

[凤凰周刊]厦门:一座岛城的化工阴影

http://ctc.webtextiles.com/info/info_228567.htm
  船驶出和平码头后,吴伟忠一直蹲在甲板上,望着海天交接处的水面。那里雾气迷蒙,一片狭长的陆地隐约呈的码头算起,直线距离不过7公里。政府在上面圈了一大片地来搞重化工,特别是PX项目,搞得人心惶惶!”
  吴所谓的PX,学名对二甲苯,属危险化学品和高致癌物。该项目由腾龙芳烃(厦门)有限公司(以下简称腾龙芳烃)投资兴建,预计2008年建成投产后,将成为中国大陆最大的PX生产企业,并将与厦门市海沧区先期建成投产的若干化工项目构建一条石化产业垂直整合带。
  海沧区目前为全国最大的台商投资区和海峡西岸重要石化基地。当地官方称,这条从PX、PTA到聚酯化纤垂直整合的化纤产业链的形成,”对海沧工业产值的拉动、工业重镇的形成以及厦门市和福建省工业产值的拉动,都将起到极大的作用。”
  而在当地民众眼中,PX为核心的产业链却成了无尽的噩梦。坊间抗议之言一直未断,但鲜受重视。
  2007年两会期间,厦门大学教授、中科院院士赵玉芬等105名全国政协委员、化学专家联名提交了一份提案,明确指出PX项目存在泄漏或爆炸隐患,对厦门市的百万人口构成潜在威胁,必须紧急叫停项目并迁址。
  至此,抗议的声音从网络走向现实,厦门民众的化工恐慌引起各方关注。 环保漏洞 吴伟忠在床上翻了个身,将脸埋进被子里。
  已经是 4月25日的凌晨时分,他还是不能入睡。几小时前,一场大雨刚刚停歇,空气里的酸臭味变的格外浓烈,厚厚的被头仍然阻挡不住气味闯入鼻腔,他濒于崩溃。
  吴翻身下床,”反正熏得睡不着,出去走走。”他离开家门,径直向小区外东面的绿化带走去,他暗自想着:”那儿花花草草的多些,或许味道会好些。”
  半道上,吴遇到邻居小周和小黄等三人。没等吴开口,小周就抢着说:”是想去呼吸新鲜空气吧,别去了,绿化带那还是一样的酸臭。”这一席话,让吴颇感郁闷,”这种日子让人怎么过!”
  吴漫无目的的在小区里走着,不时与迎面而来的邻居相视苦笑,并不言语。
  这一年多来,像吴这样的海沧区居民,似乎都成了半夜散步的”夜猫子”。吴说:”痛苦的很,晚上被熏得睡不好,白天总是无精打采,工作起来也没劲。”
  一年前,吴买下位于海沧区东南面这处小区房,搬家那天,他喊来一帮好朋友,点了一万响的电光鞭,他说,存了好多年的钱,终于有了自己的房子,可以安稳的生活,当然要开心一下,热闹一下。
  没过多久,2006年底,PX等化工项目接连上马,所有得兴奋和喜悦之情都消解在间或袭来的酸臭味中。
  吴说,现在海沧靠近化工项目的居民,很多宁愿到其他区租房子住,特别是一些待产的孕妇。
  有居民质疑,海沧区境内密布着那么多的化工厂,几年来却连个空气监近控点也没有,厦门市每天都有预报空气质量,可唯一落下的就是海沧区。”如此一来,海沧不成了环保漏洞了嘛!没人管的孩子。”
  去年7月,在民众的强烈要求和质疑声中,福建省环保局联合厦门市环保局对海沧进行了三天的空气质量监测,结果是硫化氢及臭气浓度等多项指标都超过了国家标准。
  几年前,海沧境内还没有兴建一家化工厂之时,常被厦门人称为”城市氧吧”。住在海沧农场附近的马翌城说,他家一带原先树木葱郁,又临着海,空气特别的好,”特别是爬上380多米高的蔡尖尾山上,很养生的水土和空气。”
  “我们那时都活的健康,哪里像现在,好像只是半条命了。”马说,更具杀伤力的威胁,或许是来自化工厂的泄露或者爆炸事故 。 化工产业链中的PX项目 “彼岸就是我们的梦魇!”一位居住在鼓浪屿上的居民说。
  与鼓浪屿隔海相距仅7公里的腾龙芳烃PX项目工地,占地达114。7公顷,紧邻另一座大规模的化工企业----厦门翔鹭石化及腾龙特种树脂项目。浓厚的烟尘渐次从彼此相邻的数十米高的烟囱里喷出,带着刺鼻的怪味四下弥散。
  登岸走进PX项目工地,收入眼帘的是一片宽广的寻不见确切边际的黄泥地。在这片泥地的一角,是几排简易活动房,四周散落着一些钢筋模具。PX项目的首批承建方之一的浙江东方建设集团有限公司,上百名工人正在当地温厝村附近租房待命。
  被圈入PX项目中的土地分属于温厝、渐美等几个村庄。为了圈地和施工的顺利进行,几个村庄的村民将陆续搬离。按腾龙芳烃的计划,已定制的厂区其他设备将于2008年前陆续运抵海沧,到2008年底,产量80万吨的PX项目将全面建成投产。
  PX 项目进展得非常快速,是”坐上火箭的化工项目。”已公开的消息显示,2005年7月,腾龙芳烃PX项目通过国家环保总局的环评报告审查。2006 年7月,项目获得国家发改委核准,一个月后,海沧土地开发总公司迅速开始征地。10月15日前交地。40多天征地拆迁1920亩。
  据《厦门日报》记载, 2006年11月17日,国台办常务副主任郑立中,福建省委常委、厦门市委书记何立峰,腾龙芳烃厦门有限公司董事长黄耀智,翔鹭石化企业 (厦门)有限公司董事长俞新昌共同按响动工汽笛。这标志着腾龙芳烃年产80万吨PX项目与翔鹭石化年产150万吨的PTA(对苯二甲酸)二期项目同时正式动工。
  “PX项目不同寻常!”吴伟忠说,他在报纸上看到,当时活动除了福建省和厦门市的主要领导出席外,”商务部原副部长、海峡两岸关系协会副会长安民,海峡两岸经贸交流协会会长李水林,福建省闽港、闽台、闽澳经济促进会副主任邹尔均等”也出席了动工典礼。
  “ 这是厦门有史以来投资最大的工业项目,对提升海峡西岸石化产业国际竞争力,扩大当地经济总量具有重要意义。”厦门市委常委、常务副市长丁国炎在当天的致辞中说,”PX项目的动工得到了国台办、商务部、国家发改委等国家有关部门大力帮助,体现了国家对海峡西岸建设的大力支持。”
  据介绍,腾龙芳烃厦门有限公司是中国大陆首家由外商投资,生产对二甲苯(PX)的石油化工企业,公司占地114。7公顷。腾龙芳烃作为国家重点建设项目、海峡西岸重要的石化发展基地,总投资108亿元人民币,预计2008年底建成投产。该项目建成投产后,腾龙芳烃的工业产值将达到400亿元以上。
  作为PX项目的下游,翔鹭石化PTA二期项目是厦门市重点工程。该项目到2008年底项目建成投产后,翔鹭石化的工业产值有望突破300亿元。”未来的海沧投资区,将成为世界级的芳烃系列产品制造中心。”黄耀智称。
  2002 年10月顺利投产的PTA一期项目,总投资超过50亿元,产能已达150万吨/年,是世界上单线产能最大的PTA装置,在当地官员们看来”无疑是一项成功之作”。但是在吴伟忠这样的普通民众眼里,PTA的一期工程很糟糕,让人颇感郁闷,”污染那么大,臭味也大,从它身上就能预见到以后PX项目会有多糟糕的环境危害。”
  但在官方那里,”彼岸的梦魇”似乎从未出现。2007年1月14,厦门市人民政府官方网站上发布的《向总书记报告》文章中写道:”厦门有史以来投资最大的工业项目--腾龙芳烃年产80万吨PX项目和翔鹭石化年产150万吨PTA二期项目正式动工,意味着一个世界级的’石化巨人’崛起海峡西岸,它将使福建石化产业两大重点中的聚酯化工形成中下游完美垂直整合”。
  翔鹭集团总裁俞新昌的打算是,两大项目投产后,翔鹭石化和腾龙芳烃将形成从上游至中游再至下游的化纤产业链垂直整合,达到原料自给自足、循环节能的目标。到2008年,翔鹭集团可与中石化、中石油和中燃集团比肩,并列成为中国石化”四巨头”。 网络民意难敌GDP意志? 随着PX项目推进,保护岛城免受化工侵害的抗议维权之声在网络中迅速蔓延。
  “ 一个低级且致命错误畅通无阻地进行,一座宜居的温馨的城市,也许从此只能成为记忆和梦想。”一位厦门市民在博客中说,”2005 年11月吉林双苯厂爆炸,引起的松花江污染事件,连俄罗斯人都胆惊心惊,罪魁祸首就是这种PX。人家眼里惟恐避之不及的世界级的垃圾和危险物,在我们这里成了”世界级”的宝贝,非将其插入城市的心脏不可!是谁,彻底匍匐在了资本的脚下,而置人类的自由、尊严、健康与安全于不顾?人类的信念何在?”
  身为厦门人的专栏作家连岳,也在自己的博客中说:”(PX)一旦投产,将使整个厦门本岛,甚至是人口稠密的闽南三角都笼罩在剧毒的化工阴影当中。在极端情境之下,比如战争、恐怖袭击,它就是送给对手及恐怖分子的礼物。只要这个工厂一有闪失(人命就不算了,反正也不怎么值钱),对闽南经济的致命打击,可能将损失天文数字般的GDP。”
  近年来,厦门的空气质量由全国第十沦落为2006年福建省九地市倒数第三,官方将原因归结为日益增长的汽车尾气,但是,更多的民众认为与快速崛起类似PX这样的的重化工项目关系密切。
  网名为”看海沧我的家园”的网友,在博客中指出:”中国疾病预防控制中心慢性非传染性疾病预防控制中心主任吴凡介绍,在我国,癌症患者数量奇高显然不是正常现象。如果一个地方的癌症发病率奇高,原因无非有两个:遗传病史和生存环境的巨大影响。据海峡导报2007年4月7日的报道,厦门市卫生局公布的厦门居民死亡原因是肝癌。其中海沧区、集美区的恶性肿瘤死亡率为114。00/10万;思明区、湖里区的恶性肿瘤死亡率为125。81/10万,占总死亡率的 29。25%;同安区、翔安区的居民恶性肿瘤死亡率为141。67/10万。按我国癌症的发生率约为70/10万人的比率看,厦门的居民同样处于这样一个高频发生恶性肿瘤死亡率的城市。”最后该博主质问:”是什么导致厦门,这个美丽的海岛城市上空正笼罩着高危的。。。。。。”
  对于坊间的诸多质疑,厦门官方并未一味回避。2006年12月13日,海沧投资区管委会原副主任、教授级高级工程师胡祖祥接受该报采访时表示,”先进的生产工艺,高质量、全自动、全密闭的生产设备,再加上科学严格的管理,现代化工生产的环保安全上了一个新台阶,与传统的、老旧的化工生产不可同日而语。”海沧环保分局一位负责人也说:”PX项目现场设有自动安全报警设施,如可燃气体检知器、液位报警器、火灾报警器。易爆区内则设有防爆电机、防爆灯具、防爆仪表、防爆通讯,消除引爆因素。一旦发生事故如何疏散人员,海沧区也设立了一套相应的应急措施,已经编制完成突发性环境污染事故应急预案,以有效地保障人民群众的生命财产安全。 “
  腾龙芳烃总经理林英宗也对外宣称,项目在环保方面的直接投资达4。7亿元,占总投资额的5%-7。5%。但有分析文章指出,千里之外的宁波,投资的聚氯乙烯(PVC)项目在环保方面的投资已占总投资额的20%左右。
  不过网络舆论普遍认为,官员们更多的言论则表明,网络上广泛的民意轻易就会被GDP意志所消解。
  2007年1月30日,厦门市工业经济暨品牌工作会议上提出,随着工业集中区的大规模开发建设及PX、PTA等一批大项目的相继建设,今年该市工业总产值预期完成2800亿元,力争达到3000亿元。
  “两大项目(PX和PTA)预计投产后产值达800亿元以上。”厦门市委常委、海沧区委书记钟兴国也在一篇题为《借东风鼓浪扬帆聚合力跨越发展》的讲话稿中说。此前,他曾对外透露,2005年海沧的工业总产值达到464。1亿元,
  在厦门市各区、开发区中名列第一,其中石化化工产业的贡献率达到五成以上。
  2月8日,厦门市委领导在海沧区调研时强调,要”继续保持金戈铁马、狂飙突进的态势和气势”,”统一思想,提高认识,珍惜机遇,全力以赴抓好征地拆迁,切实保障好PX、PTA二期等重点工程建设”。

  院士联名上书

  2007年春天的全国政协会议上,院士赵玉芬、原北京航空航天大学校长沈士团、院士田中群等105位政协委员联名提交了一份议案,要求叫停厦门PX项目。
  网络民意至此获得了更为有效的上呈路径,开始引发更多关注和讨论。
  据赵玉芬等化学专家的调研示意图显示,海沧PX项目中心地区距离厦门市中心和国家级风景名胜区鼓浪屿均只有7公里,距离拥有5000名学生(大部分为寄宿生)的厦门外国语学校和北师大厦门海沧附属学校仅4公里。不仅如此,项目5公里半径范围内的海沧区人口超过10万,居民区与厂区最近处不足1。5公里。大陆《石油化工企业卫生防护距离》中规定,年产20万~60万吨涤纶的企业,当地风速2~4m/s时,卫生防护距离应为900米。
  与赵玉芬一起进行调研的厦门大学化学教授袁东星指出,”类比涤纶企业,海沧PX和PTA项目的卫生防护距离也应为900米。但事实是,海沧兴港花园住宅区离翔鹭石化PTA项目不足
500米。”
  而10公里半径范围内,覆盖了大部分九龙江河口区,整个厦门西海域及厦门本岛的1/5。而项目的专用码头,就在厦门海洋珍稀物种国家级自然保护区,该保护区的珍惜物种包括中华白海豚、白鹭、文昌鱼。
  “PX(对二甲苯)是一种危险的化学品,也是高致癌物,极易导致胎儿畸形。”赵玉芬在接受大陆媒体访问时说,”再好的环保措施,安全性也仍存在隐患,我们根本不能用爆炸或泄露的可能性来衡量,一旦发生危机,后果不堪想象。”赵玉芬说。
  厦门主城区位于一座岛屿上,即俗称的厦门本岛,上有湖里和思明二区。本岛只有两座跨海大桥与外界相连,一是位于本岛西北连接集美区的厦门大桥,另一座是位于本岛西南连接海沧区的海沧大桥。
  赵质疑,”一旦海沧PX 项目发生极端事故,或者是危及该项目安全的自然灾害,如台风、地震、海啸,乃至恐怖威胁,厦门本岛的上百万居民,不知要花多少时间从四车道的厦门大桥撤离?”
  资料显示,国际上的PX项目集中在亚洲地区,尤以韩国和中国为多,台湾地区和韩国等地的项目与较大城市的直线距离一般大于70公里,而中国大陆则一般约20公里。例如,韩国年产40万吨PX的LG
  Galtex公司距离光州87公里,马来西亚年产45万吨PX的AMSB公司距吉隆坡238公里,泰国年产11万吨PX的ATC 公司距春武里52公里。而在国内,同样年产80万吨PX的扬子石化,离南京市25公里;建设中的年产60万吨PX的洋浦开发区,距海口市128公里;建设中的年产45万吨 PX的福佳大化距大连市17公里;建设中的年产70万吨PX的中金石化距宁波18公里;而年产65万吨PX的台湾六轻工业区,距台中市 70公里。可见,厦门年产80万吨的PX项目距市中心仅7公里,是目前国际国内距离最近的项目。
  国家环保总局副局长潘岳曾指出,中国化工石化行业存在的严重布局性环境风险,是近年来突发性环境污染事故激增的根本原因。有些建设项目,单个考虑时似乎都符合环保标准,有的甚至达到了先进水平;但是从区域环境容量或区域规划角度评估,多个项目放在一起又明显不合理。
  2007年3月14日上午,国家环保总局环评司司长祝兴祥在潘岳副局长的授意下,与参与提案的沈士团与田中群等委员进行沟通
  。大陆媒体透露说,”祝兴祥也似乎无能为力,因为一个根本的问题是,项目投产是国家发改委批的,国家环保总局在项目迁址问题上根本没有权力。针对该单个项目的环评早已通过。环保总局现在唯一能做的就是,就是对厦门市绝不再批新的化工项目。” 阴影的背后 “在腾龙芳烃问题上,缺乏全面有效的环境披露和公众参与,而置民众的安全于险境,又是一种什么样的罪错?”有观察人士认为,厦门面临的化工污染阴影的背后,是中国大陆城市功能区规划中的环评公众参与的缺失。
国家环保总局在2006年2月22日发布《环评公众参与暂行办法》时特别指出:公众参与是解决中国环境问题的重要途径,而环境信息披露制度是公众参与环境事务的前提。
  国务院《关于落实科学发展观加强环境保护的决定》指出,”实行环境质量公告制度,定期公布各省市有关环境保护指标,发布城市空气质量、城市噪声、饮用水水源水质、流域水质、近岸海域水质和生态状况评价等环境信息,及时发布环境事故信息,为公众参与制度创造条件。”
  “大家都在质疑,专家也参与了,但目前好像还没有出现关键性的解决路径。”吴伟忠说,4月28日又是一个周末,他没有呆在家里休息,和几位邻居乘船出海,他们都不愿呆在臭味熏人的家里,”那差不多是慢性自杀”。

厦门px项目(转贴)

天涯杂谈---转贴 
px简介:
  PX就是对二甲苯,属危险化学品和高致癌物,对胎儿有极高的致畸率
  (国家院士赵玉芬语)
  项目规模:
  年产80万吨px
  项目地点要求:
  “联苯厂存在特别重大的安全性隐患,是不能靠近城市的,至少要建立在100公里以外,城市才能算安全。”赵玉芬说。
  实际项目地点安排:
  该项目中心地区距离厦门市中心和国家级风景名胜区鼓浪屿均只有7公里,距离拥有5000名学生(大部分为寄宿生)的厦门外国语学校和北师大厦门海沧附属学校仅4公里。
  不仅如此,项目5公里半径范围内的海沧区人口超过10万,居民区与厂区最近处不足1.5公里。而10公里半径范围内,覆盖了大部分九龙江河口区,整个厦门西海域及厦门本岛的1/5 。而项目的专用码头,就在厦门海洋珍稀物种国家级自然保护区,该保护区的珍惜物种包括中华白海豚、白鹭、文昌鱼。
  历史事件:
  2005年11月吉林双苯厂爆炸
   昨天13时45分,地处吉林省吉林市的中国石油吉林石化公司双苯厂(又称101厂)新苯胺装置发生爆炸。截至18时许,共发生爆炸15起,其中较大爆炸6起,化工区附近数万居民及大学生被紧急疏散;该起事故已造成近70人受伤,其中2人重伤,另有6人失踪。
   苯,顺着消防用水流进松花江 导致松花江发生重大环境污染 哈尔滨停水一周 连俄罗斯人都胆战心惊 海外评价恶劣
   国家环保总局局长解振华因“对事件重视不够,对可能产生的严重后果估计不足”,辞去了国家环保总局局长的职务。
  项目危险性估计:
  “再好的环保措施,安全性也仍存在隐患,对此,我们根本不能用爆炸或泄露的可能性来衡量,因为一旦发生危机,后果不堪想象,损失不是多少个亿的GDP能弥补的。”(赵玉芬语)
  这个危险项目与城市中心区域只有10公里,
  海沧区原本规划出的隔离带,出于商业考虑已经完全盖满了学校与住宅,一旦投产,将使整个厦门岛,甚至是人口稠密的闽南三角都笼罩在剧毒的化工阴影当中。在极端情境之下,比如战争、恐怖袭击,它就是送给对手及恐怖分子的礼物。只要这个工厂一有闪失(人命就不算了,反正也不怎么值钱),对闽南经济的致命打击,可能将损失天文数字般的GDP。
   厦门本岛的出口道路只有两条,一是位于本岛西北连接集美区的厦门大桥,另一则是位于本岛西南连接海沧区的海沧大桥。海沧PX 项目一旦发生极端事故,或者是危及该项目安全的自然灾害,如台风、地震、海啸,乃至恐怖威胁,厦门本岛的上百万居民,不知要花多少时间从四车道的厦门大桥撤离?
  大事记:
  2006年7月 国家发改委批准总投资额达108亿元人民币的PX(对二甲苯)项目落户厦门海沧
  2007年3月
    两会期间,以国家院士赵玉芬教授为代表的105个政协委员齐声呼吁,联名签署了关于厦门海沧PX项目迁址建议的议案”,成为今年政协的头号重点议案。
   “厦门危险,PX项目必须紧急叫停,并进行迁址!”
   2007年3月14日 国家环保总局表示无能为力
  国家环保总局环评司司长祝兴祥在潘岳副局长的授意下召见了提案代表。
  对这一问题表示了莫大认同和理解的祝兴祥也似乎无能为力,因为一个根本的问题是,项目投产是国家发改委批的,国家环保总局在项目“迁址”问题上根本没有权力。
  “针对该单个项目的环评早已通过。环保总局现在唯一能做的就是,就是对厦门市绝不再批新的化工项目。”来自环评司的一位内部人士告诉记者。
  后记:
   厦门是一个得过“最佳人居奖”的城市 难道就要因此蜕变成一颗重磅炸弹?请政府听听民声 听听105权威专家的意见 请大家都来关注厦门

Wednesday, May 23, 2007

《还是朋友》

         昨夜小雨淅沥,辗转反侧,难以入睡,却听一首《还是朋友》:

如果爱情会老
会不会有爱的勇气
窗外还下著雨
滴落著对你的思绪
怕喝醉眼前一片漆黑
怕失去知己再也难追
世间痴情的戏
等待有心人去看清

为何相爱相知相信相聚还不够
见你深夜徘徊冷漠的脸好难过
就算爱情到了尽头
不再有结果
我们还可以是朋友

你说朝夕相处平平淡淡太寂寞
难道深情褪色对你的好也是错
就算缘份到了尽头
无力再挽留
我们还可以是朋友
还是朋友

Thursday, May 3, 2007

梦回五四

         睡觉前照常听了会歌,靡靡之音中渐入梦乡,做了一个离奇的梦。一时惊醒,梦中情景历历在目,难以再寐,遂下床写下此篇以记之。
         那是九十五年前,四万万中国人在巨变之后不久迎来了第一个新年,年轻人们满怀希望地憧憬着未来,一切似乎都是新的,就连这个节日的名字也是新的——春节。梦中的我在街上游荡,用好奇的眼光看着周围过去早就熟悉的一切,然而完全不同的感觉。这个时候一个女孩闯入了我的视野,我的心莫名地紧张起来。那种感觉是那么的奇怪,不可言状,不可捉摸。我总是想看清她的脸,却总是看不清;我拼命挤开人群想接近她,却总也无法接近她。时间好像突然静止了,又好像突然过去了很长时间;当梦继续时,我似乎明白了一切,似乎知道了她的一切。时间是跳跃的,我们俩变得亲密无比。然而,我总是以为她会离我而去,她却总是告诉我她会回来;我很想知道她要去哪里,却总是听不清她的答案。当我的身边不再有她时,世界变成了灰色,不再有声音;濛濛的小雨湿透了我的心,也浇灭了希望的火种,孤独与彷徨中延续着我的梦……
         七年后的五月四号,我和人们高呼着口号走上街头,然而我听不见声音,也看不见颜色,只感觉到有水流淌在脸上,不知是泪还是雨。子弹飞来的瞬间,我的身体变得轻盈无比,离开了地面,飞跃了千山万水,回到了曾经寻找她的地方,在那里我占据了一片净土,永远地占据了。春去秋来,我对她的思念像周围的小草一样生生灭灭,无穷无尽。春天,我的泪水滋润着初生的小草,不顾冬天的凛冽严寒;秋天,寒风摧残着小草瘦弱的身影,不顾夏日里的勃勃生机。终于,有一天,我来了两位客人,一对外国夫妇。他们一步步地走近,我的心也渐渐地明白,想起了她曾经在我耳边说过的答案,无比的清晰响亮。风吹弯了小草的腰,我靠近地面想扶起它们,在那瞬间,我分明看到了她洒落在小草上那晶莹的泪。

Wednesday, March 14, 2007

无题

         今天和人闲扯时,想到一个好玩的测试题。大致情节是这样的,一个日本人到中国出差,不幸的是在首都机场他将手机和钱包都丢了,接他的人也不知何因未至。这位日本仁兄长得是典型的日本人,而且看起来就不象是好人,因此无法向人求助(情节所须耳,不必较真);好在他是位运动健将,马拉松高手,他决定跑步到市区。问题是,他以前都是坐车走高速去市区的,他只认识这条路,高速上是不允许有行人的,而且其时已晚,跑得那么快没准被当成贼抓起来。那么他应该怎么办?
         我的办法是写个标语,比如“关爱中国儿童,支持希望工程”(英文怎么讲?),挂在胸前,直接冲向高速。想象一下,如果在美国,或许会有一堆人象追随阿甘一样追随他,然后他成为名人....;在中国,公安会问明缘由,将其送到目的地,第二天报纸会说“为了希望工程,日本友人从东京跑步至北京,人民公仆助其完成心愿....”。

Sunday, January 28, 2007

梦蛇

         我是很少做梦的人,仅做的几个梦至今记忆犹新。昨晚(准确而言是今天上午)居然梦见了蛇。梦中,先是斩杀大蛇,根据以后情节计算,应为蛇王,然不知是青蛇还是白蛇;总之,是很凶猛的那种蛇,理应可以在“狂蟒之灾”中谋得一个角色。继而回家(亦或是军营或衙门),恐群蛇因失王而报复村民,遂点数十神箭手往抄蛇窟。不意大败,虽奋勇杀数蛇,无奈寡不敌众,只得落荒而逃,心想这么多蛇只能调坦克来打了....
         小时候也做过一次关于蛇的梦,梦中孤身被群蛇追赶,醒后犹悸,妈妈安慰我说梦见蛇是吉兆,我才放下心来。和这次不同的是,小时后的那次蛇都很小,而且我只是跑;这次,显然大有进步。
         在网上搜了一下梦蛇,概要看了一下,俱是胡扯,遂尝试自己解梦。本人没读过多少古书,只记得高祖斩白蛇而起义,资治通鉴有如下描述:刘季被酒,夜径泽中,有大蛇当径,季拔剑斩蛇。有老妪哭曰:“吾子,白帝子也,化为蛇,当道。今赤帝子杀之!”因忽不见。前半部分颇为相似,刘邦终得天下,开大汉四百年基业,然史书述及此却总云“斩白蛇而起义”,可见斩蛇当为吉兆。古人又尝以蛇论天下形势,资治通鉴卷一百十五有云:天下若常山蛇势,秦、蜀为首,东南为尾,中原为脊;将图恢复,必在川、陕。蛇还能体现中华地势!蛇是吉兆的另外一件明证,就是“龙”和“蛇”常一起被人提起,天上为龙,地下为蛇。传说中蛇本为龙,犯天律而被逐,然天帝选十二生肖时终不敢漏之,龙蛇遂并入。杜甫有诗云:禹庙空山里,秋风落日斜。荒庭垂橘柚,古屋画龙蛇。云气生虚壁 江深走白沙。早知乘四载,疏凿控三巴。龙蛇被做为天子的象征画在禹庙中。另有诗云:殿上衮衣明日月 砚中旗影动龙蛇。曹操的《龟虽寿》更是以蛇代龙:神龟虽寿,猷有竟时。腾蛇乘雾,终为土灰。老骥伏枥,志在千里;烈士暮年,壮心不已。盈缩之期,不但在天;养怡之福,可得永年。幸甚至哉!歌以咏志。还有人用蛇来喻棋局:局合龙蛇成阵斗,劫残鸿雁破行飞。从天干地支上来说,巳(蛇)与亥(猪)相冲,2007是亥(猪)年,猪年斩蛇也算一吉。
         最后用列子中的一句话结束本篇吧:藉带而寝则梦蛇;飞鸟衔发则梦飞

Friday, January 26, 2007

         没想到今天竟然下起了小雨。泥土变得很松,草倒还是很有精神,踩上去别有一番异样的感觉。自从8号到达总部,已经三周了,一直很忙。前段时间每天只睡7个小时不到,今天实在没精神做很多事情。恰逢周五,公司里人很少,于是偷空写篇blog。
         公司所在地Mountain View处于硅谷的中心地带、Palo Alto区域内,西北方向40分钟左右的路程就是San Francisco,再往北就是著名的Gold Gate Bridge。Standford和Berkeley都在附近,Standford尤其近,我估计走路过去一个小时就到了。Moutain View算是比较偏僻的地方,丘陵地带;因此没有车的话就寸步难行了。昨天晚上和北京那边开完会后,我独自一人走了40多分钟回到公寓,很累,没想到今天老天就感动得哭了,:)。一路都是上下坡,中间闯了无数红灯,主要是路上没车红灯还亮着,老是忘了按那个按钮。顺便说一下,美国人也闯红灯,只要路上没车的话;我前几天曾看到一对老夫妻很悠闲地携手共闯红灯。开车的人大多比较文明,会让行人先走;主要是一旦出了事故,后果很严重,所以他们都很小心。但并不是绝对的,我昨天回去穿过一个路口的时候,发现一个车想闯过去,我很鄙视地望了他一眼,他就停下来让我先走了。
         相对于国内来说,这里的路更像马路。科普一下什么叫马路,摘自wikipedia:
现代一般称的行车路“马路”,被视为是“马卡丹路”的简称。约翰·马卡丹(John McAdam,1756年-1836年)是苏格兰裔的道路工程师。工业革命时期发明了新的道路建造法(Macadam),在路面铺上多层物料,并把路面设计成让雨水流到路的两旁。这样,行车路便更耐用持久,满足了工业发展所导致的陆路运输需求。
         美国的路都修得很丰满,能看出很明显的拱形,路面也很平整。国内下雨时常出现雨水流不走积在“马路”上的情况,这里是不会有的。Mountain View没有高楼,我们住的公寓大约5、6层的样子,已经算是高的了。每家每户都住在那种单独的房子里,不知可否称为别墅。每个房子都被路环绕着,真正的四通八达。即使是房子中间的路也修得一丝不苟,也就是说和大路一样干净和像“马路”。这些路一般都是没名字的,而且有的还相当大;所以出行时要记住目的地的路名和需要经过几个桥,千万别数路口。有名字的路在交汇的地方通常都会在路灯上挂个很大的灯具写上路名,晚上也能看得很清楚;我昨晚第一次走回公寓,就是这样找路牌回去的。路多的坏处是路口太多,走几步就是一个路口,很多路口是不设红绿灯的,而是在路上画一个STOP的标志;意思是开车到这里的时候必须先停下车,并向左右两个方向看看再继续。路面和路边到处都是各种标志,指示如何选择路口、能否转弯和停车等。大路都会有couple道,只允许至少载两人的车行驶,以此来鼓励多人出行以减少汽油使用量。
         而且美国的路是不收费的,一些大桥是例外。来的第一个周末和同学到Berkeley逛了一圈,回去经过Bay Bridge的时候好像是堵车了,以为前面出了什么状况,后来发现要收费;我们来的时候是没收费的,所以没想到,不过就4美金,比国内的还是便宜多了。

Saturday, January 6, 2007

两个家庭:被房价改变的生活

轉貼南方周末的一篇文章,看完之后有種莫名的忧伤。媽媽好幾次勸我早点買房,說把她的那點錢給我再加上我一兩年的工資把首付付了。我坚持不买。并不是坚信房价会跌;我只是认为这是不对的。也许是由于无数人对房价持续上涨的恐惧而产生的買房潮造成的恶性循环;也许是因为银行和房产商勾结;也许是因为那些有钱人的“圈房运动”;也许正如某些“先进者”的教导,我们就是应该付出这么多钱。如果是前三种,我不应该買房,我不能屈服于恐惧。如果我买了,当我住上自己的房子时,面对仍然持续上涨的房价,我想我不能感到幸运;难道不正是由于千千万万像我这样買房的人导致了更多和我一样的人需要付出更多不该付的钱?我不能指责那些買房的人,我可以做到不買房。如果是最后一种,那么我宁愿为自己的愚蠢买单;我想那时也许我并不在乎那點買房的钱。那么,我有什么理由買房呢?

  昔日“被迫”,如今“庆幸”的决定。
  看着几乎一天一变脸的房价,郝虎一直在庆幸自己当初的决定,尽管这个决定是被迫做
出的。
  2003年那场可怕的非典,让郝虎和女朋友顾青都感到生命无常。当时,研究生快毕业的
顾青正在学校准备GRE考试,不料,非典越来越凶,身边竟也有同学感染,还有老师的家属
因此去世,最后整个学校都被封了。每天郝虎端着在租住的房子里熬好的鸡汤去看顾青,两
人隔着学校锈迹斑斑的铁栅栏说几句话,聊几句天。郝虎要顾青坚强,相信一定会有两人拥
抱的那一天。顾青满眼泪水,在满世界的消毒药水味道中,郝虎熬的鸡汤飘着惊人的香气。
  在北京“解除隔离”的那一天,顾青决定嫁给郝虎,但遭到了父母的反对。原因是郝虎
没有房。郝虎在北京的一家国有大型设计院工作,单位承诺会集资建房,再以成本价卖给职
工(因为政策有限制,不允许叫“集资建房”,叫“公房上市”),但是得排年头,哪年能排
上要看和领导的关系如何。领导经常对郝虎说:“小郝啊!你好好干啊!房子会有的!”
  郝虎心知肚明,分在同一设计院的大师兄孩子都好几岁了,也没有排上集资建房的队。
他对此不抱太大希望。看看外面的商品房,拿事业单位工资的郝虎觉得力不从心。
  可是不能因为没有房子就不结婚呀!郝虎心里暗暗使劲。那天在未来的丈母娘家,郝虎
再次展示了他的招牌鸡汤,二老连连说好,但到了房子问题上,态度还是那么坚决。其实顾
青家并不缺房,但长辈就是不想让女儿吃亏。有房子是男人有能力的标志。
  郝虎决定自己动手、丰衣足食。他先找到小商贩刻了个“萝卜章”,然后伪造了一份经
济适用房申请的单位收入证明。之所以不找自己的领导去开,是因为这种大型国有事业单位
的“办公室政治”比企业有过之而无不及,更重要的是要是知道你自己在外面买了房,单位
的排队房就会彻底泡汤了。
  郝虎去那个超大型的经济适用房售楼处时,脸上在滴滴答答地淌着汗。天热是一方面,
心里实在是太紧张了。郝虎从小到大,一直是标准的好学生,从不说谎。不过今天,郝虎决
定拼了。
  出乎他意料的是,售楼大姐只是轻轻瞟了一眼他的证明,就开始让他选户型和位置,并
没有为难他的“萝卜章”。郝虎大声地呼了一口气,北京夏日低闷灰暗的天空好像瞬间开阔
了。
  几个月之后,郝虎和顾青如愿住进了新居,婚礼也是在新房举行的。婚礼那天,郝虎喝
得酩酊大醉,心里却异常的踏实———在这个1000多万人口的大都市,终于有一室灯光是属
于自己的了。不过,他对未来的交通生活其实是准备不足的。
  郝虎的工地在东四,每天从北五环外到东四单程至少一个半小时。天不亮就走,天黑才
回家,真正的披星戴月。而那小区正处于城乡接合部,路况极差,每天都有一片一片的人在
等着几辆仿佛马上要被涨破肚子的公交车。郝虎最终选择冒着生命危险坐“蹦蹦车”去地铁
站。一辆辆绿甲壳虫般的蹦蹦车颠簸在土路上,好像随时都会散架,而身边经常是驮满水泥
的大货车呼啸而过。郝虎总觉得如果那些大车撞上他坐的“蹦蹦车”,会像大象踩死一只蚂
蚁那么容易。
  
  两年时间房价翻番
  就在郝虎挣扎在上下班路上的时候,大学同学李木来到了北京。李木是郝虎最好的朋友
和老乡。大学毕业后,分回了新疆的设计院。在他们工程行业,新疆的设计院比北京的体制
更加僵化。李木看着设计院的老同志们,就能想象自己在这里退休时的样子,干一样的活,
喝一样的茶,吃一样的饭。李木选择奋力一搏,毅然辞去了设计室副主任的职务,卖掉设计
院分给他的房子,揣着十几万元来到了北京。
  和他一起来北京的还有他刚结婚的妻子武静,新疆大学中文系的研究生。刚来北京,中
文系的研究生就领教了找工作难的程度。她一再降低身份,最后在一所小学的分校当起了临
时老师,每个月只有两千块钱。
  李木正准备把从新疆带来的钱在北京付个房屋首付的时候,家里传来了不好的消息——
父亲食道癌做手术需要不少钱。李木没什么犹豫,将八万块钱寄回了家。父亲是这个家的天
。李木永远忘不了,有一年自己腿摔骨折了,父亲用自行车推着他去上学。新疆的雪啊!一
直会下到人膝盖那么厚。父亲就推着车在雪里艰难地挪着步,并把围巾围在李木的脖子上。
当时李木就在想,如果将来哪天自己念书念出来了,一定要好好报答一下父亲。可现在呢?
医生说,幸亏发现得早,生存的希望是很大的。李木对不想做手术的父亲发了火,说就算为
了他也要做。李木还要把父母接到北京来,帮他们带孩子呢!
  寄钱回家给父亲的事情,武静什么话也没有说。但是李木知道,她是不高兴的。武静一
直在乌鲁木齐长大,吃苦不算多。现在为了保证不因堵车而迟到,要每天6点钟起床,骑大
半个小时的车去上班,北京冬天的大风有时会把人吹跑,冷得疼到人的骨头里。武静一直在
看学校周围的房子,甚至选好了一个小户型。每当李木心疼她,想把租房子的地点换到离她
学校近一点的时候,她总是说:“这不是快买房了吗?就几个月了,现在这边的房租比那边
便宜不少。”
  一下子拿走了八万,首付肯定是不够了,哪怕是最小的户型,而且身处北京,总得手头
留一点余钱,万一生个病什么的,医药费会像吸血鬼一样一个晚上花光你所有的储蓄。“没
关系,我们还年轻,再攒两年钱,肯定就能买了,别着急!”李木充满惭愧地鼓励道。出于
内心的愧疚,李木还是把家搬到了离武静学校近的地方,宁愿自己骑自行车外加挤公交地受
折磨。
  然而,事情完全出乎李木的料想,北京的房价这两年像是坐上了热气球。当年他们看好
的房子均价6000多元一平方,现在已经涨到了12000元,而且还没有小户型。李木的工资从
原来的4000多涨到6000多,武静也不过三千出头,去掉交房租和日常开销,对于北京均价10
000元一平方的房子,无论如何也拿不出首付了。关键是这种趋势丝毫没有逆转的兆头。房
价还是在顽强地创新高,任李木、武静怎么踮脚蹦高都够不着。
  
  被房价改变的爱情
  武静的话明显少了,她本来就不是一个很爱说话的人。租来的房子里,夏天蚊子多得要
命,而且好像蚊子都具有了超强的耐药性,电蚊香、杀虫剂,什么招都用上了,还是越用越
多。即使隔着蚊帐,武静也曾经多次在半夜被蚊子咬醒过,抓得浑身都是包,有的包破了,
鲜血淋漓。之后,武静就睡不着了,偷偷地哭。
  李木睡得轻的时候会马上爬起给她擦药水,再安慰安慰她。然而,就连李木自己都觉得
自己的安慰是那么脆弱而轻微。什么时候能体面地住进新房?李木觉得自己就像一颗尘埃,
飘浮在北京浑浊的空气中。他开始怀疑自己当初的选择,看起来北京真不是什么人都能闯的

  眼看着春节就要到了,武静给李木发了一条短信说希望谈谈。李木预感到了什么,只是
没有想到这么突然和直接———离婚。
  春节前夕,李木来到郝虎家吃饭。顾青几乎可以完整复制郝虎的鸡汤了。只喝了几口汤
,李木就开始大口喝酒,边喝边哭:“我不怪她,她不是因为不爱我,而是因为看不到希望
。你说谁不想和希望待在一起?你说对吗?虎子!”李木越喝越多,越哭越凶,郝虎和顾青
根本拦不住。李木的眼泪滴在鸡汤里,油花一漂一漂的。
  深夜了,李木一身酒气,却执意要走,郝虎没有办法,动了手,最后大喊道:“李木,
你这么没有出息吗?现在会比我们上学时从新疆回学校的火车上更难吗?”
  是的,现在肯定没有那个时候难。从四川到新疆的72小时里,只能坐着睡觉。没有坐过
三天三夜的人不会理解那种滋味,脚肿得粗粗的,人的脑子里则一直有着干脆从车上跳下去
的念头。有一次,武静和同学去四川玩,回来的时候为了陪同学选择了坐火车,一上车,她
就后悔了,但也只能硬着头皮坐下去。她的座位正好挨着李木,聊聊天就算认识了。熟悉了
些之后,李木把自己的座位让给武静躺下睡,而自己则睡在座位底下。看着李木睡得香甜,
武静仿佛被什么烫了一下。
  夜更深了,郝虎家的几座塔楼像金刚战士般任凭狂风呼啸也巍然屹立,注视着世间的一
切。
  (所有被访者均为化名)