2007年3月17日星期六

N天以来关于变态比赛的研究~(效率有点慢)

哈哈 经过N天不懈的努力(好像都是玩了~~)终于对这个[变态比赛规则]程序算法有了一定的心得!!~~首先,介绍一下在网上搜到的高人的算法(听说这个题目的算法还不少,但是除了"暴力"递归的我认为在众多的程序中,这个写的比较好.复杂度要比光递归小了好多)
#include

int main(int argc, char *argv[])
{
int n, k;

/*if( argc!=3 )
{
printf("use: %s n k", argv[0]);
return -1;
}

n = atoi(argv[1]);
k = atoi(argv[2]);*/
scanf("%d %d",&n,&k); //input two numbers

if(foo(n, k)>0)
printf("YES\n");
else
printf("NO\n");

return 0;
}

int maxT(int n, int m)
{
if( n<=0 n>500 m<=0 ) return -1; if( m==1 ) return n*(n-1)/2; if( m>=n n==1 )
return 0;
return m*(n-m)+(n-m)*(n-m-1)/2;
}

int minT(int n, int m)
{
if( n<=0 n>500 m<=0 ) return -1; if( m==1 ) return n*(n-1)/2; if( m>=n n==1 )
return 0;
return m*(n-m)+minT(n-m, m);
}

int foo(int n, int k)
{
int max, min;
int m;

if( n<=0 n>500 k<0>n*(n-1)/2 )
return -1;

if( k==0 k==n-1)
return 1;

if( n==1 k0; m-- )
{
max = maxT(n, m);
min = minT(n, m);
if( k<=max &&amp;amp; k>=min )
{
if( foo(n-m, k-m*(n-m))>0 )
return 1;
}
}
return -1;
}

然后,再介绍一下我这几天的心得了.我就是在读这段程序时(呵呵,至今我还没有完全搞明白段代码是个什么意思~~ 那位高手来给点拨一下啊.谢谢!),基本上看懂一点,但是突然受到这段代码的启发,想到了一个算法.首先,我一开始是摸不着头脑,只是明白了按规则最多应该有N*(N-1)/2场比赛[每组一个人],最少应该有N-1场比赛[一组一个人,其他人一组].或者0场比赛[所有人一组].后来换个角度来考虑,觉得不应该从有K场比赛,如何分这N个人来考虑.应该考虑一下有N个人,如何分组才能有这K场比赛.另外,也不应该把所有人分在一组,然后分开一个,然后再一个...这样反倒没有规律了.后来想到如果一开始是每一个人一组,然后没人之间都有比赛这样就是一个完全无向图.而合并一组就是把组内的边除去.也就是m个人分为一组的话,就从N阶完全无向图中除去一个m阶完全无向图.
就这样一直合并直到能得到K条边为止,或者只能得到一个小于K的边数.至于具体的算法我还没写出来^_^!! 同时也不知道这个算法是否可行.拭目以待了^_^!!

2007年3月12日星期一

关于Astar2006-3变态比赛规则的进一步讨论

首先,关于题目的补充要求(我们老师没有这样的要求,只是要求算法尽量的优化就可以了):
1.程序将运行在一台Linux机器上(内存使用不作严格限制),在每一测试数据集上运行不能超过10秒,否则该用例不得分;
2.要求程序能按照输入样例的格式读取数据文件,按照输出样例的格式将运行结果输出到标准输出上。如果不能正确读入数据和输出数据,该题将不得分;
3.该题目共有3个测试数据集,每个测试数据集为一个输入文件。各测试数据集占该题目分数的比例分别为30%,30%,40%;
经过考虑我把题目抽象为N个元素,分为m组.每组人数为A1,A2,......,Am(均不为空[≠0]).其中
A1+A2+...+Am=N
A1(N-A1)+A2(N-A1-A2)+...+Am(N-A1-A2-...-Am)=K
用递归来解决,每次递归k值都在减少Am(N - Am),基于以上公式对Am递增,递归,回溯所有组合即可得出答案
在网上搜到一位牛人的文章中这样说:
这题我是O(n^4)的记忆化搜索。用了一种技巧合并状态。所以复杂度估计也只有O(N^3), 跑出所有数据在自己机上是5s.代码写的相对简单漂亮
呵呵,真想知道他这个算法是怎样的一个算法.

[转贴] 写的很好啊 幽默~~ 心声~~

Five reasons why you should marry me
A friend sent me the following in an email. It is so numerically funny.Five reasons why you should marry me -
1. I am a mature, responsible adult now:

2. I am a nice gentlemen, everyone likes me:

3. so many things I enjoy, spending time with you is my first choice:

4. I am the only one that matches you !

5. I love to save the world. Let us do it together !

嘿嘿



大家觉得怎么样呢? 可爱吧 真是原来世界上还有这么可爱的女生啊~~
Posted by Picasa

2007年3月11日星期日

作业题

AStar2006百度之星程序设计大赛试题

3.变态比赛规则 为了促进各部门员工的交流,百度举办了一场全公司范围内的“拳皇”(百度内部最流行的格斗游戏)友谊赛,负责组织这场比赛的是百度的超级“拳皇”迷W.Z。W.Z不想用传统的淘汰赛或者循环赛的方式,而是自己制定了一个比赛规则。
由于一些员工(比如同部门或者相邻部门员工)平时接触的机会比较多,为了促进不同部门之间的交流,W.Z希望员工自由分组。不同组之间的每两个人都会进行一场友谊赛而同一组内的人之间不会打任何比赛。

比如4个人,编号为1~4,如果分为两个组并且1,2一个组,3,4一个组,那么一共需要打四场比赛:1 vs 3,1 vs 4,2 vs 3,2 vs 4。 而如果是1,2,3一组,4单独一组,那么一共需要打三场比赛: 1 vs 4,2 vs 4,3 vs 4。

很快W.Z意识到,这样的比赛规则可能会让比赛的场数非常多。W.Z想知道如果有N个人,通过上面这种比赛规则,总比赛场数有可能为K场吗?比如3个人,如果只分到一组则不需要比赛,如果分到两组则需要2场比赛,如果分为三组则需要3场比赛。但是无论怎么分都不可能恰需要1场比赛。
相信作为编程高手的你一定知道该怎么回答这个问题了吧? 那么现在请你帮助W.Z吧。

输入要求:

每行为一组数据,包含两个数字 N, K( N∈(0,500] K∈[0,+∞) )。例:

2 0

2 1

3 1

3 2

输出要求:

对输入的N,K 如果N个员工通过一定的分组方式可以使比赛场数恰好为K,则输出"YES",否则输出"NO"(请全部使用大写字母),每组数据占一行。例:

YES

YES

NO

YES

这就是这个学期的课程设计的变态题目了,完完全全是一个解决问题的算法题目。寒假里恶补的数据库看来是用不上了。今天才拿到这个题目,没有头绪勒。看看再说吧

PS到这种地步了 厉害啊 我要好好学习PS了 呵呵~~
Posted by Picasa

2007年3月9日星期五

通知

鉴于近段时间以来 Blogger的访问速度奇快无比 因此决定启用我闲置已久的blogger来作为我以后的blog的主要网站 ~~! 谢谢各位一直以来对我的无私支持与关怀~~!! 我会作的更好的~~!!!

2006年10月15日星期日

MM Posted by Picasa

2006年10月12日星期四


girl Posted by Picasa