• 网志分类
  • » 查看所有日志 (45)
    » ACM (24)
    » 程序设计语言 (3)
    » 我的软件 (5)
    » 转贴 (12)
    » 被遗忘的角落 (1)
  • 最新评论
  • 站内搜索
  • 友情链接
  • » 我的歪酷 非非共享界
    » kuye
    » 开复学生网

    订阅 RSS

    歪酷博客

    0011506

    kodder @ 2007-12-06 05:05

     OI论坛

    http://acm.zjnu.cn/ 浙江师范大学软件协会(上面有许多acm的资料)

    高级编程
    http://www.csdn.net/ CSDN.NET - 中国最大的开发者网络

    Java相关
    www.java2s.com/

    计算机软件理论
    www.math.ucla.edu/~tom/Game_Theory/Contents.html
    www.chinaai.com

    ACM Online Judge
    http://www.topcoder.com/tc
    http://icpc.baylor.edu/icpc/
    http://acm.pku.edu.cn/JudgeOnline/  
    http://acm.timus.ru/  
    http://acm.sgu.ru/  
    http://online-judge.uva.es/problemset/  
    http://acm.zju.edu.cn/  
    http://www.spoj.pl/  
    http://ace.delos.com/usacogate2

    开源

    http://www.uclinux.org/
    http://www.netbsd.org/

    嵌入式

    www.51eda.com/
    http://www.laogu.com/
    http://www.21ic.com/

     







     
    kodder @ 2007-11-12 07:55

    内存管理
    一个典型的指令执行周期,首先从内存中读取指令。接着该指令被解码,且可能需要从内存中读取操作数。在指令对操作数执行后,其结果可能被放回内存。
    输入队列:在磁盘上等待调入内存以便执行的进程。
    源程序中的地址通常用符号表示。编译器通常将这些符号地址捆绑在可重定位的地址。连接程序或者加载程序再将这些地址重定位的地址捆绑成绝对地址。
    内存管理单元:运行时从虚拟地址到物理地址映射;
    内存分配方式:

    1.         连续内存分配

    内存通常分成两个区域,一个用户驻留操作系统,另一个用于用户进程。
    分配策略,将内存分成多个固定大小的分区。每个分区只能容纳一个进程,当一个分区空闲时,可以从输入队列中选择一个进程,以调入到空闲分区,当进程退出时,该分区可以被其他进程使用。
    孔:所有内存可用于用户进程因此能够作为一个大块可用内存。
    具体方法如下:
           一组大小不同的孔分散在内存中。当新进程需要内存时,系统为该进程查找足够大的孔(查找方法有首次拟合,最佳拟合,最差拟合),如果孔太大,就将该孔分成两部分,其中一部份用于分配给新进程,另一部分返回系统。具体高地址,或者低地址区域于具体的系统。当进程终止时,内存被回收,如果发现该内存和其他内存块相邻,就将他们合并成一个大块。

    2.          



     
    kodder @ 2007-11-10 13:02

    复合交互任务

    1.         复合交互任务主要有三种形式:

    a)         对话框,用于指定多个信息单元;

    对话框是一种菜单,它将一直保持可见,直到用户显示地关闭它。
    一般情况下用户关闭了对话框了,才能够使得对新的设置起作用,但是也有是用户按下了对话框下的应用按钮后才起作用。

    b)        构造,用于创建需要两个或更多位置的对象;

    橡皮筋技术
    橡皮筋线技术:当用户按下按键时光标建立起了直线段到起始端点,随着光标的移动,直线段也跟着移动。
    橡皮筋矩形技术:从一个按键动作开始,这个按键动做确定了矩形的一个角点,然后它的对角点和光标动态地联系在一起,随着光标移动而移动,直到释放按键为止。
    橡皮筋园技术:创建一个园,该园的圆心由初始的光标为止决定。
     

    c)        操纵,用于对已经存在的几何对象进行重定形

    在光标的控制下,拖动选定的符号从一个位置移动到另外一个位置。通常按下按键动作开始拖动,然后一个释放按键的动作将符号固定在新的位置,随后的光标移动对符号没有影响。这个按下按键,拖动,释放按键的序列通常称为点击-拖动交互

    2.          



     
    kodder @ 2007-11-08 00:02

    文件系统的实现

    1.         文件系统的结构

    磁盘的特点
           1. 可以原地重写,可以从磁盘上读一块,修改该块,并将它写回到原来的位置
           2. 可以直接访问磁盘上任意一块信息。
    一般访问磁盘上的数据块由:驱动器,柱面,磁道,扇区标识
    逻辑文件系统管理元数据。元数据包括文件系统的所有数据结构,而不包括实际数据。

    2.         磁盘的结构

    引导控制块: 包括系统从该分区引导操作系统所需要的信息,linux下为第一个扇区MBR

    分区控制块:包括分区详细信息。 如分区的块数,块的大小,空闲块的数量和指针,空闲块FCB的数量和指针等,NetBSD下有个超级块就是这个结构。

    3.         虚拟文件系统VFS

    VFS通过定义一个清晰的VFS接口,以将文件系统通用操作和具体实现分开。
    VFS是基于vnode。该结构包括一个数值指定者以表示位于整个网络范围内的唯一文件。

    4.         磁盘分配方法

    连续分配: 连续分配方法要求每个文件在磁盘上占用一组连续的块。因为是连续分配的,导致文件的创建的时候必须指定大小,而且创建好后的大小也就不能够扩充了。但它的一个优点是访问效率比较高。因为文件中的所有数据都是连续放在一起的。读取数据时的寻道时间将是最短,此类方法实现的文件系统一般效率比较高,但有内部碎片。

    链接分配:相比连续分配,它使用磁盘块中4个字节的指针左右指向下一个数据块的地址。因而将整个文件的数据块链接成一个链表。 此种方法没有磁盘内部碎片,但是因为是将数据块链接陈一个链表,不够安全,如果一个指针被破坏了增文件的链表可能就坏了,还可能影响到整个文件系统。另外对它优化的一种方法是使用双向链表,或则将多个块组成一个簇。

    5.         索引分配

    独立分配出一个数据块存放索引结构,相当与将此前链表中所有的指针域全部按照顺序放到一个索引块中。


     
    kodder @ 2007-11-07 23:59

    Windows中有关GDI

    1.         画点相关的。

    SetPixel函数在指定的xy坐标以特定的颜色设置象素

    SetPixel(hdc, x, y, color)

    GetPixel函数返回指定坐标处的象素颜色

    Color = GetPixel(hdc, x, y)

    2.         画线

    Windows 可以画直线椭圆线和贝塞尔样条
    LineTo 画直线
    PolyLinePolyLineTo 画多组相连的线
    Arc 画椭圆线

           函数原型是Arcconst CRect &rect int xStartint yStart, int xEnd, int yEnd

    PolyBezierPolyBezierTo画贝塞尔样条
    ArcTo AngleArc画椭圆线
    设备描述表(DC)的5个属性影响着这些函数画线的外观:
           当前画笔的位置
           画笔
           背景方式
           背景色
           绘图模式

    3.         填充区域

    Windows 中有7个用来画带边缘的填充图形的函数
    Rectangle 直角矩形
    Ellipse 椭圆
    RoundRect 圆角矩形
    Chord 椭圆周上的扇形
    Pie椭圆周上的扇形
           以上两个函数的区别是函数Pie画扇形的时候要经过椭圆的中心,而Chord画椭圆的时候直接链接弧的开始坐标和结束坐标所形成的扇形,函数的原型如下:
           Pieconst CRect &rect int xStart, int yStart, int xEnd, int yEnd

    Chordconst CRect &rect int xStart, int yStart, int xEnd, int yEnd

     
    Polygon 多边形
    PolyPolygon 多个多边形
    绘制方式:Windows 中使用DC中的当前画笔来画图形的边界框,边界框还使用背景色,当前背景方式和绘制方式。图形以DC中选择的画刷来填充。
    多边形填充的方式一般有两种ALTERNATEWINDING,其中ALTERNATE的方式使用就在多边形填充的时候使用标准的扫描转换可以得到,至于另外一个属性据说也是同一个算法可以得到,但是我还不清楚。
    画刷是一个8x8的位图
           常用情况下区域的背景使用画刷就足够了,但是有些情况下除了画刷还要使用另外一种画刷,叫做影线画刷。Windows中使用函数CreateHatchBrush()来创建。
    它提供了6中不同的影线画刷。

    l         水平影线

    l         垂直影线

    l         交叉影线(同时具有水平影线和垂直影线功能。

    l         左倾斜影线

    l         右倾斜影线

    l         交叉斜影线(有左斜影线和右斜影线合成)

    4.         设备坐标和逻辑坐标

    Windows对所有的消息都是使用设备坐标,而不像DC 中一样使用逻辑坐标
    WindowsGDI函数中指定的逻辑坐标映射成设备坐标,因此在GDI函数中一些参数往往都是逻辑坐标。
    整窗口坐标:以程序整个窗口为基准,如标题栏,菜单,滚动条和窗口边框都包括在内。
    客户区坐标:点(00)就是客户区的左上角,当使用GetDC获取设备描述表的时候GDI函数中的逻辑坐标就会转换成客户去坐标。
    用函数ClientToScreenScreenToClient可以将客户区坐标转换为屏幕坐标,或者反过来将屏幕坐标转换为客户去坐标。

    5.         窗口和视口的区别

    视口:是基于设备坐标的,通常和客户区相同
    窗口:机遇逻辑坐标的

    6.         矩形和区域裁剪,区域就是屏幕上的一块地方,他是矩形,多边形和椭圆的组合。

    FillRect(hdc, &rect, hBrush);

    FrameRect(hdc, &rect, hBrush);

    invertRect(hdc, &rect)

    FillRect用指定的画刷来填充矩形,该函数不需要先将画刷选进DC
    FrameRect使用画刷来画矩形框,但不填充。
    InverRect将巨型中的象素翻转。

    7.         创建和绘制区域

    通过将区域选进设备描述表,就可以用区域来进行裁剪。
    CreateRectRgn(&rect)
    CrecteEllipticRgn(&rect);

    CreatePolygonRgn(&point, &iCount, iPolyFillMode);

    区域的操作

    CombineRgn(hDestRgn, hSrcRgn1, hSrcRgn2, iCombine);

    iCombine参数说明了hSrcRgn1hSrcRgn2如何组合
    RGN_AND            两个区域的公共部分
    RGN_OR              两个区域的全部
    RGN_XOR            两个区域的全部去掉公共部分
    RGN_DIFF           hSrcRgn1不在hSrcRgn2中的部分
    RGN_COPY          hSrcRgn1的全部。
     



     
    kodder @ 2007-08-26 22:26

    UVA110 题目要求输入一个整数,然后输出一个pascal的可运行的程序,但程序中只能宥比较,ifelseif else等的语句,在程序中使用了递归算法,写好后觉得这个类似与一个生成1.。。。n的所有数的排列数
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
     
    #define MAX 9
    #define STEP 2
     
    struct meta {
           int num;
           int var[MAX];
    } Meta;
    void space(int n)
    {
           for (int i = 0; i < n; i++) printf(" ");
    }
    void out(const struct meta &Meta)
    {
           for (int i = 0; i < Meta.num - 1; i++) printf("%c,", 'a' + Meta.var[i]);
           printf("%c", Meta.var[Meta.num - 1] + 'a');
    }
    void swap(int *a, int *b)
    {
           int t = *a;
           *a = *b;
           *b = t;
    }
    // insert after the index element....
    void move(const struct meta &in, struct meta &o, int index, int len)
    {
           int i, t;
          
           o = in;
           t = in.var[len - 1];
           for (i = len - 1; i > index; i--)
                  o.var[i] = o.var[i - 1];
           o.var[i] = t;
    }
    void meta_loop(struct meta Meta, const int index, const int indent)
    {
           struct meta tmp;
           int i;
     
           i = index - 1;
           space(indent); printf("if %c < %c then\n",
                               Meta.var[i] + 'a', Meta.var[index] + 'a');
           if (Meta.num - index == 1) {
                  space(indent + STEP); printf("writeln("); out(Meta); printf(")\n");
           } else
                  meta_loop(Meta, index + 1, indent + STEP);
           for (i--; i >= 0; i--) {
                  space(indent); printf("else if %c < %c then\n",
                                      Meta.var[i] + 'a', Meta.var[index] + 'a');
                  move(Meta, tmp, i + 1, index + 1);
                  if (tmp.num - index == 1) {
                         space(indent + STEP); printf("writeln("); out(tmp); printf(")\n");
                  } else
                         meta_loop(tmp, index + 1, indent + STEP);
           }
           move(Meta, tmp, 0, index + 1);
           space(indent); printf("else\n");
           if (tmp.num - index == 1) {
                  space(indent + STEP); printf("writeln("); out(tmp); printf(")\n");
           } else
                  meta_loop(tmp, index + 1, indent + STEP);
    }
    int main(void)
    {
           int i, j, n;
           char buf[32];
     
           gets(buf); sscanf(buf, "%d", &n);
           gets(buf); // just ignore the empty line.
           for (i = 0; i < n; i++) {
                  gets(buf); sscanf(buf, "%d", &Meta.num);
                  if (i != n - 1) gets(buf); // there will be a blank line between test cases.
                  for (j = 0; j < Meta.num; j++) Meta.var[j] = j;
                  printf("program sort(input,output);\nvar\n");
                  out(Meta);printf(" : integer;\nbegin\n");
                  space(2); printf("readln(");out(Meta);printf(");\n");
                  if (Meta.num == 1) {
                         space(2); printf("writeln(a)\n");
                  } else
                         meta_loop(Meta, 1, 2);
                  printf("end.\n");
                  if (i != n - 1) printf("\n");
           }
           return 0;
    }


    UVA112 这道题目相对前一道题目比较简单,因为毕业设计的做的是编译原理方面的。这倒题目类似建立一个语法树,然后对这个语法树进行遍历,计算出根节点到叶节点的路径。。。
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <limits.h>
     
    static int total;
    static int flag;
     
    struct tree {
           int n;
           struct tree *pleft, *pright;
    };
     
    void skipspace()
    {
           char ch;
     
           while (1) {
                  ch = getchar();
                  if (ch == ' ' || ch == '\n' || ch == '\t') continue;
                  else break;
           }
           ungetc(ch, stdin);
    }
    int GetInt()
    {
           int n, mark = 1;
           char ch;
          
           skipspace();
           n = 0;
           if ((ch = getchar()) == '-')
                  mark = -1;
           else n = ch - '0';
           while (isdigit(ch = getchar())) {
                   n = n*10 + ch - '0';
           }
           ungetc(ch, stdin);
           return n*mark;
    }
    char GetChar(void)
    {
           skipspace();
           return getchar();
    }
    void match(const char c)
    {
           char ch = GetChar();
     
           if (ch != c) {
                  //assert(0);
                  //printf("yeah...... invalid tree\n");
                  flag = 1;
           }
    }
    struct tree * build_tree()
    {
           struct tree *root = NULL;
     
           match('(');
           char ch = GetChar(); ungetc(ch, stdin);
           if (isdigit(ch) || ch == '-') {
                  root = new struct tree;
                  root->n = GetInt();
                  root->pleft = build_tree();
                  root->pright = build_tree();
           }
           match(')');
           return root;
    }
    int search_tree(struct tree *root, int value)
    {
           if (!root) return 0;
           if (root->pleft == NULL && root->pright == NULL) {
                  value += root->n;
                  return value == total;
           }
           if (root->pleft && search_tree(root->pleft, value + root->n)) return 1;
           return root->pright ? search_tree(root->pright, value + root->n) : 0;
    }
    void print_tree(struct tree *root, int indent)
    {
           if (!root) return;
           for (int i = 0; i < indent; i++) printf(" ");
           printf("%d\n", root->n);
           print_tree(root->pleft, indent + 2);
           print_tree(root->pright, indent + 2);
    }
    void destroy_tree(struct tree *root)
    {
           if (root) {
                  destroy_tree(root->pleft);
                  destroy_tree(root->pright);
                  delete root;
           }
    }
    int main(void)
    {
           struct tree *root;
           int ch;
     
           while ((ch = GetChar()) != EOF) {
                  ungetc(ch, stdin);
                  flag = 0;
                  total = GetInt();
                  root = build_tree();
                  if (flag == 1 || !search_tree(root, 0)) printf("no\n");
                  else printf("yes\n");
                  //print_tree(root, 0);
                  destroy_tree(root);
           }
           return 0;
    }