« March 2006 | Main

April 24, 2006

Problem 2723(半素数)

题目定义了一种叫半素数的数:只要一个数能被分解成两个素数,那么这个数就是半素数。
Prime Number Definition
An integer greater than one is called a prime number if its only positive divisors (factors) are one and itself. For instance, 2, 11, 67, 89 are prime numbers but 8, 20, 27 are not.

Semi-Prime Number Definition
An integer greater than one is called a semi-prime number if it can be decompounded to TWO prime numbers. For example, 6 is a semi-prime number but 12 is not.

Your task is just to determinate whether a given number is a semi-prime number.

Input

There are several test cases in the input. Each case contains a single integer N (2 <= N <= 1,000,000)

Output

One line with a single integer for each case. If the number is a semi-prime number, then output "Yes", otherwise "No".

Sample Input

3
4
6
12

Sample Output
No
Yes
Yes
No

没什么好说的,解法很简单,解法如下:

#include <iostream>
#include <cmath>
using namespace std;
bool isprime(long test)
{
     int i;
     for(i=2;i<=sqrt((long double)test);i++)
     {
          if(test%i ==0)
               return false;
     }
     return true;
}
bool isSemiPrime(long test)
{
     int i;
     for(i=2;i<=sqrt((long double)test);i++)
     {
          if(test%i ==0)
          {
               int temp = test/i;
               return isprime(i) && isprime(temp);
          }
     }
     return false;
}
int main()
{
     long n;
     while(cin>>n && n !=0)
     {
          if(isSemiPrime(n))
               cout<<"Yes"<<endl;
          else
               cout<<"No"<<endl;
     }
}

April 22, 2006

征求虚拟主机合租者

最近买了DreamHost虚拟主机服务,经过一段时间的试用,总体感觉还行。
Herock的Blog上看到合租一个空间的主意,我一个人也用不掉这么多空间,也决定征集10个左右的合租者,而且最好也是Blogger,可以顺便认识一些优秀的Blogger。如果你想搭建一个自己的Blog或者网站并且对这个合租计划有兴趣的话请联系我吧。
当然和Herock一样,我不欢迎那些提供违反国家法律的色情、赌博、反动等信息资料、还有mp3, 软件下载等服务的人士,原因大家都清楚,这些服务会严重影响其他合租者。
按照Herock的合租的价格我适当做了一些下调(数字好听点^_^),
初步定为¥88元/年包括
# 1个 FTP用户(300M(update 现为1G
# 和我共享1000G/月的流量(每周增加8G、单用户不得超过200G/月)
# 2个 Mysql数据库
# 支持无限顶级域名(需自己准备)
# 无限子域名(如果你不准备购买域名,我可以送你一个xxx.zhuxinquan.com二级域名)
# 支持CGI,PHP,Perl
# 不支持ASP
# 支持数据备份

每增加100M空间¥38元/年
每增加1个Mysql数据库¥18元/年

联系方式email

至于Web访问速度,你可以测试一下连这个Blog的速度。

另外值得一提的是,因为这款空间的管理权限只有一个,所以像域名的解析、数据库的管理等等,只能由我来操作,有一点点的麻烦,这也是对我信誉度的考验,你只能相信我。

(update 合租已满,但你也可以联系我,如果有人到期退出,我会通知你)
有任何问题也可以在这里留言。

April 21, 2006

Problem 2722(淘汰赛问题)

题目:
Our school is planning to hold a new exciting computer programming contest. During each round of the contest, the competitors will be paired, and compete head-to-head. The loser will be eliminated, and the winner will advance to next round. It proceeds until there is only one competitor left, who is the champion. In a certain round, if the number of the remaining competitors is not even, one of them will be chosed randomly to advance to next round automatically, and then the others will be paired and fight as usual. The contest committee want to know how many rounds is needed to produce to champion, then they could prepare enough problems for the contest.

Input
The input consists of several test cases. Each case consists of a single line containing a integer N - the number of the competitors in total. 1 <= N <= 2,147,483,647. An input with 0(zero) signals the end of the input, which should not be processed.

Output
For each test case, output the number of rounds needed in the contest, on a single line.

Sample Input
8
16
15
0

Sample Output
3
4
4

题目比较简单,下面是我给的解法。其实就是计算一个数是2的几次方。

#include <iostream>
using namespace std;
long calculate(long test)
{
     long ret = 0;
     bool is2square = true;
     while(test!=1)
     {
          if(test % 2)
               is2square = false;
          test /= 2;
          ret++;
     }
     if(!is2square)
          ret++;
     return ret;
}

int main()
{
     long n;
     while(cin>>n && n !=0)
     {
          cout<<calculate(n)<<endl;
     }
}

What Do MSN Technologies (China) Do ?

From :
http://spaces.msn.com/ligongatmsn/blog/cns!1130EB21E0E5C23!108.entry?_c=BlogPart

Since I joined Microsoft (MS) to be the Managing Director of MSN Technologies (China) (which let us refer to as MSNTC) almost 2 months ago, a lot of people ask me what MSNTC does. Here is a rough outline, and is my estimate and subject to change without notice :-)

1. MSNTC is a part of the worldwide MSN business group (one of the 7 business groups, or BGs, in MS).

2. MSNTC covers all R&D activities of MSN in China.

3. 80-90% of what we do would be worldwide MSN projects, such as Messenger, Hotmail, etc. 10-20% of what do would be targeted at China and the Asian region specifically, for example to make msn.com.cn more competitive.

4. We will grow to multiple hundreds of people very quickly, in both Beijing and Shanghai. We may have other locations, but so far the focus is in BJ and SH.

5. We welcome folks who want to return from abroad, but their expectations have to be in line with reality in China. Unless they are super special, or with a lot of MS experience in the US, they would normally not be paid a premium since the local talent in China is very strong.

For those people who actually are interested in finding out what sort of jobs are available in MSNTC, here are a few things to keep in mind.

(a) MSNTC has all sorts of opennings, from admins to developers to managers to program managers ... but MS is somewhat different from other multinationals in how they are organized (see below).

(b) A first-line manager is called a Dev Lead (Development Lead) or Test Lead. So if you are used to sporting a manager title, be prepared for this change. (But I guess in Chinese the title for Dev Lead can still be Manager? Have to check.) And Dev Leads are expected to be extremely hands on, so if you are a pure people manager, it is going to be hard for you to be a Dev Lead.

© A second-line manager is called a Dev Manager, who typically manages Dev Leads and others. This manager can also be very hands-on, but can also somewhat more focused on project and people management.

(d) A PM (program manager) usually is very technical. Apart from managing product schedules and dependencies, a PM at MS is expected to drive product feature spec and such. There are PM ladders, such as LPM (Lead PM) and GPG (Group PM), for larger projects.

(e) Test leads are usually regular employees but testers are typically outsourced to vendor companies.

Note the above are just rules of thumb and you will find out more accurate info if you talk to MS at some point.

Finally, I am busy hiring a few hiring managers. Once they come on board, perhaps in the next couple of weeks, they will turn around and start hiring like crazy. I am sure they will make their contact information known to all those who want to know :-)

So much for today.

Cheers,

Li Gong

April 11, 2006

激情与梦想

如果没有梦想,就不会有激情,如果没有激情,就难以体味淋漓畅快的人生。by k_eckel
这正是现在的我所需要的两样东西。

April 10, 2006

链表反转

单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题。比如一个链表是这样的: 1->2->3->4->5 通过反转后成为5->4->3->2->1。最容易想到的方法遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历。源代码如下:

struct linka {
     int data;
     linka* next;
};

void reverse(linka*& head)
{
     if(head ==NULL)
          return;
     linka*pre, *cur, *ne;
     pre=head;
     cur=head->next;
     while(cur)
     {
          ne = cur->next;
          cur->next = pre;
          pre = cur;
          cur = ne;
     }
     head->next = NULL;
     head = pre;
}

还有一种利用递归的方法。这种方法的基本思想是在反转当前节点之前先调用递归函数反转后续节点。源代码如下。不过这个方法有一个缺点,就是在反转后的最后一个结点会形成一个环,所以必须将函数的返回的节点的next域置为NULL。因为要改变head指针,所以我用了引用。算法的源代码如下:

linka* reverse(linka* p,linka*& head)
{
     if(p == NULL || p->next == NULL)
     {
          head=p;
          return p;
     }
     else
     {
          linka* tmp = reverse(p->next,head);
          tmp->next = p;
          return p;
     }
}

April 02, 2006

判断两个数组中是否存在相同的数字

给定两个排好序的数组,怎样高效得判断这两个数组中存在相同的数字?
这个问题首先想到的是一个O(nlogn)的算法。就是任意挑选一个数组,遍历这个数组的所有元素,遍历过程中,在另一个数组中对第一个数组中的每个元素进行binary search。用C++实现代码如下:

bool findcommon(int a[],int size1,int b[],int size2)
{
     int i;
     for(i=0;i<size1;i++)
     {
          int start=0,end=size2-1,mid;
          while(start<=end)
          {
               mid=(start+end)/2;
               if(a[i]==b[mid])
                    return true;
               else if (a[i]<b[mid])
                    end=mid-1;
               else
                    start=mid+1;
          }
     }
     return false;
}

后来发现有一个 O(n)算法。因为两个数组都是排好序的。所以只要一次遍历就行了。首先设两个下标,分别初始化为两个数组的起始地址,依次向前推进 。推进的规则是比较两个 数组中的数字,小的那个数组的下标向前推进一步,直到任何一个数组的下标到达数组末尾时,如果这时还没碰到相同的数字,说明数组中没有相同的数字。

bool findcommon2(int a[], int size1, int b[], int size2)
{
     int i=0,j=0;
     while(i<size1 && j<size2)
     {
          if(a[i]==b[j])
               return true;
          if(a[i]>b[j])
               j++;
          if(a[i]<b[j])
               i++;
     }
     return false;
}

最大子序列

问题:
给定一整数序列A1, A2,... An (可能有负数),求A1~An的一个子序列Ai~Aj,使得Ai到Aj的和最大
例如:
整数序列-2, 11, -4, 13, -5, 2, -5, -3, 12, -9的最大子序列的和为21。
对于这个问题,最简单也是最容易想到的那就是穷举所有子序列的方法。利用三重循环,依次求出所有子序列的和然后取最大的那个。当然算法复杂度会达到O(n^3)。显然这种方法不是最优的,下面给出一个算法复杂度为O(n)的线性算法实现,算法的来源于Programming Pearls一书。

在给出线性算法之前,先来看一个对穷举算法进行优化的算法,它的算法复杂度为O(n^2)。其实这个算法只是对对穷举算法稍微做了一些修改:其实子序列的和我们并不需要每次都重新计算一遍。假设Sum(i, j)是A[i] ... A[j]的和,那么Sum(i, j+1) = Sum(i, j) + A[j+1]。利用这一个递推,我们就可以得到下面这个算法:

int max_sub(int a[],int size)
{
     int i,j,v,max=a[0];
     for(i=0;i<size;i++)
     {
          v=0;
          for(j=i;j<size;j++)
          {
               v=v+a[j];//Sum(i, j+1) = Sum(i, j) + A[j+1]
               if(v>max)
                    max=v;
          }
     }
     return max;
}

那怎样才能达到线性复杂度呢?这里运用动态规划的思想。先看一下源代码实现:

int max_sub2(int a[], int size)
{
     int i,max=0,temp_sum=0;
     for(i=0;i<size;i++)
     {
          temp_sum+=a[i];
          if(temp_sum>max)
               max=temp_sum;
          else if(temp_sum<0)
               temp_sum=0;
     }
     return max;
}

在这一遍扫描数组当中,从左到右记录当前子序列的和temp_sum,若这个和不断增加,那么最大子序列的和max也不断增加(不断更新max)。如果往前扫描中遇到负数,那么当前子序列的和将会减小。此时temp_sum 将会小于max,当然max也就不更新。如果temp_sum降到0时,说明前面已经扫描的那一段就可以抛弃了,这时将temp_sum置为0。然后,temp_sum将从后面开始将这个子段进行分析,若有比当前max大的子段,继续更新max。这样一趟扫描结果也就出来了。