http://acm.nyist.net/JudgeOnline/problem.php?pid=540
今年省赛时的第一道题。欢迎大家去刷河南省赛题。
一周没有刷题,回生了,这么一道题花了两个多小时。真不该跟妹子聊天。
题意:按数字倒序后的大小排序。
本打算把数字转为字符串,然后对字符串用strcmy(),发现这样是不对的,应为"11"会小于"8",而事实是相反的。后来想到用两个数组存原数和倒序后的数,按倒序后的数排序后输出正序的数字,终于A了。汗啊。
注意cmp()函数的写法。


posted @ 2012-05-23 23:28 小鼠标 阅读(250) | 评论 (0)编辑 收藏
     摘要: 回溯算法的经典例题。大一的时候就有耳闻,却一直没有实现,今天终于有机会把它写出来,小有成就感啊。这里算法采用的是深度优先搜索,从第一个节点开始,按行优先的原则逐个扫描每个点,如果该点合法,可以选择放一个queen也可以选择不放,当该点不合法时,就跳过该点接着判断下一个点。有人把回溯算法说成是“万能算法”,这么说的原因是回溯实际上就是枚举,它的最坏情况始终是指数或阶乘级的。对...  阅读全文
posted @ 2012-05-11 20:24 小鼠标 阅读(401) | 评论 (0)编辑 收藏

大数加法,字符串处理。关键是细节,这方面的问题我老是把边界下标搞错,比如这次就是因为访问到了数组的len元素而导致结果出错。
关与加法的策略:
以前未解决两个家数的对齐问题,我会先把两个字符串倒序,相加、进位后再倒回来,感觉这样到来倒去的实在麻烦。
现在顿悟了,果断不再倒序,从字符串的高下标处开始相加两个数,只要有数字的下标低于1(0位用来保存进位)就停止。具体做法是:
1.用c(指针)记录较长的那个数字
2.预处理:把a、b数组内的字符转化为数字
3.从a、b数组的高下标处(实际加数的低位)开始相加数字a、b
4.从数字的高下标处开始处理进位
5.完成处理:把数字转化为字符
注意:消除和的前导0


 

posted @ 2012-05-11 19:05 小鼠标 阅读(137) | 评论 (0)编辑 收藏
完全背包。
要点:
1.要求价值的最小值
2.要求背包正好装满

posted @ 2012-05-09 18:23 小鼠标 阅读(136) | 评论 (0)编辑 收藏
看了这么多天的背包,总算渐渐开始理解了。
背包问题有很多种,基本的有两种:0-1背包和完全背包。多重背包可由这两种组合得来。
本题是多重背包问题,可以简单的将多重背包直接转化为0-1背包来求解,但是这种转化很有可能导致超时,因为物品数量太多了。可行的办法是利用 二进制状态压缩,这样可以大大减少物品数量(实际物品数量只有log(N)件)。

posted @ 2012-05-09 09:51 小鼠标 阅读(143) | 评论 (0)编辑 收藏

赤裸裸的0-1背包,很水。听说省赛要出DP题,我们队三个人都不擅长DP,于是乎我开始从背包问题入手学习动态规划。看了几天的背包,头都大了,还是不理解,今天终于A掉了一道水题,值得纪念一下。
关于背包这里就不多说了,感兴趣的童鞋可以参考《背包问题九讲》。


 

posted @ 2012-05-08 09:47 小鼠标 阅读(222) | 评论 (0)编辑 收藏
     摘要: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3204一道很直接的最小生成树,题中给出了权值矩阵,本应给用Prim的,但是为了练习一下并查集的使用,选择了Kruskal。前面我写过Kruskal,但是集合的表示用的是线性表,每次合并都要花费O(N)的时间,效率较低。这次用了并查集——集合的树形表示,...  阅读全文
posted @ 2012-04-26 10:01 小鼠标 阅读(296) | 评论 (0)编辑 收藏
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=914
最小生成树prim算法。
最近刚学过Dijkstra的最短路算法,仔细分析一下,Dijkstra与Prim算法十分相似,区别在于更新点时的标准不同。前者是该点到起点的距离(用dist[]记录)最小,则将该点加入s,并更新相应的dist[],后者是该点到s中任意一点的距离(用lowcost[]记录)最小,则将该点加入s,并更新相应的lowcost[]。
说来惭愧,这一题错在了格式上,没有认真读题,多保留了一位小数。
经验总结:认真读题。

posted @ 2012-04-25 21:58 小鼠标 阅读(122) | 评论 (0)编辑 收藏
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2750
成语接龙问题,抽象出来就是简单的最简单的单源最短路径问题,Dijkstra算法。
算法设计课上刚讲过贪心算法,Dijkstra算法书上有代码实现,比着书上的代码copy了一遍,提交后居然奇迹般的出现了段错误!这叫我情何以堪啊。FAQ上说段错误有两种情况:数组下标越界和栈溢出。算法中没有递归,不可能爆栈,认真检查每一个用到下标的地方、每个for的起始点,看不出任何毛病。难道代码比着书上抄错了,对照了一下,发现第二个循环开始时没有初始化u,问题就出在这里,u是用来记录下一个可加入集合s的节点的,它的更新来自于所有可利用的dist[]中最下的那个。
经验总结:变量不要忘记初始化。

#include<stdio.h>
#include
<string.h>
#include
<stdlib.h>
#define LENID 1050
#define RMAX 10000
#define LENS 8
typedef 
struct
{
    
char *a;
    
char *b;
    
int t;
}
Idiom;
int N;
int dist[LENID];
int c[LENID][LENID];
int Dijkstra()
{
    
int i, j;
    
int s[LENID];
    
    
for(i = 0; i < N; i++)// init
    {
        dist[i] 
= c[0][i];
        s[i] 
= 0;
    }

    dist[
0= 0;
    s[
0= 1;
    
    
int u = 0;// remeber to init u!!
    for(i = 0; i < N - 1; i++)
    
{
        
int temp = RMAX;
        
for(j = 0; j < N; j++)
        
{
            
if(s[j] == 0 && dist[j] < temp)
            
{
                u 
= j;
                temp 
= dist[j];
            }

        }

        s[u] 
= 1;
        
if(u == N - 1)
        
{
            
return dist[u];
        }

        
for(j = 0; j < N; j++)
        
{
            
if(s[j] == 0 && c[u][j] < RMAX)
            
{
                
int newdist = dist[u] + c[u][j];
                
if(newdist < dist[j])
                    dist[j] 
= newdist;
            }

        }

    }

    
return dist[N - 1];
}

int main()
{
    
int T;
    
int i, j;
    Idiom id[LENID];
    
char str[100], sa[8], sb[LENS];
    scanf(
"%d"&N);
    
while(N != 0)
    
{
        
for(i = 0; i < N; i++)
        
{
            scanf(
"%d%s"&T, str);
            
int len = strlen(str);
            
for(j = 0; j < 4; j++)
            
{
                sa[j] 
= str[j];
                sb[j] 
= str[len - 4 + j];
            }

            sa[j] 
= sb[j] = '\0';
            id[i].a 
= (char *)malloc(sizeof(char* LENS);
            id[i].b 
= (char *)malloc(sizeof(char* LENS);
            strcpy(id[i].a, sa);
            strcpy(id[i].b, sb);
            id[i].t 
= T;
        }

        
for(i = 0; i < N; i++)// init c[][]
            for(j = 0; j < N; j++)
                c[i][j] 
= RMAX;
        
for(i = 0; i < N; i++)
            
for(j = i + 1; j < N; j++)
            
{
                
if(strcmp(id[i].b, id[j].a) == 0)
                    c[i][j] 
= id[i].t;
                
else if(strcmp(id[j].b, id[i].a) == 0)
                    c[j][i] 
= id[j].t;
            }

        
int r = Dijkstra();

        
if(r == RMAX)
            printf(
"-1\n");
        
else
            printf(
"%d\n", r);
        scanf(
"%d"&N);
    }

}


posted @ 2012-04-25 18:08 小鼠标 阅读(301) | 评论 (0)编辑 收藏
算法的效率异常重要,对于一个专业的计算机人员来说,应将效提高算法率放在心里,时刻注意。这种思想应该深入我们的骨髓,成为一种习惯。
以前我写过pow函数,不过那都没动脑子,简单的线性时间运算。这里有一个O(logN)的算法,值得一提。
int Pow(int x, int n)
{
    
if(n == 0)
        
return 1;
    
if(n == 1)
        
return x;
    
if(n % 2 ==  0)
        
return Pow(x * x, n / 2);
    
else
        
return Pow(x * x, n / 2* x;
}
算法虽然简单,但却体现了编程工作者应具备的基本素质。
posted @ 2012-04-23 09:14 小鼠标 阅读(309) | 评论 (0)编辑 收藏
仅列出标题
共13页: First 5 6 7 8 9 10 11 12 13 
<2013年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

随笔分类(111)

随笔档案(127)

friends

最新评论

  • 1. re: 线段树
  • 是这个样子的,所以在OJ有时候“卡住”了也不要太灰心,没准真的不是自己的原因呢。
    加油,祝你好运啦!
  • --小鼠标
  • 2. re: 线段树
  • 对于编程竞赛来说,Java所需时间一般为C/C++的两倍。合理的竞赛给Java的时间限制是给C/C++的两倍。
  • --伤心的笔
  • 3. re: poj1273--网络流
  • 过来看看你。
  • --achiberx
  • 4. re: (转)ubuntu11.10无法启动无线网络的解决方法
  • 膜拜大神。。查了一个下午资料终于在这里解决了问题。。神牛说的区域赛难道是ACM区域赛。。?
  • --Hang
  • 5. re: 快速排序、线性时间选择
  • 博主,谢谢你的文章。你的方法可以很好的处理分区基准在数组中重复的情况,书上的方法遇到这种输入会堆栈溢出。书上给出了解释但给的方法貌似不简洁。
  • --lsxqw2004

阅读排行榜