博客

  • 谷歌Office无法访问

    https://docs.google.com/ 无法访问的解决方法,首先将系统盘\Windows\system32\drivers\etc\hosts 如: C:\Windows\system32\drivers\etc\hosts 在结尾处加上:
  • 自己改的python

      想在Ubuntu里面弄桌面幻灯片,到网上搜了一下,找到了python文件生成XML的方法,也知道了Ubuntu用XML来使用桌面幻灯片,用了下试试,发现总有一段纯色的时间,没办法,硬着头皮看了看代码,发现python,至少是这个python文件很容易懂,估计问题大概是处在一个."的上面,这样的话会把所有文件枚举一次,就可能把自己枚举或者是那个XML文件(估计是这样,这是第一次接触python。)然后就只留下了".jpg"的内容,奇迹般地就好了,也大概知道了在XML里面设置停顿时间和切换时间。
      不过我批评python一下,我真不喜欢用缩进来写代码的(上面这些都是自己摸索的,没搜资料!)
      原python如下:
    #!/usr/bin/env python
    # –
    – coding: utf-8 ––
    # Name:  slidexml.py
    # Author: EthanZ6174
    #        Email: <heracles.621@gmail.com>
    #        Site: http://www.noslog.com
    # Licence: GPLv3
    # Version: 091127

    import glob, os
    import shutil
    import time

    curdir = os.getcwd()
    os.chdir(curdir)
    currentFilelist = glob.glob(‘
    .‘)
    currentImageFiles = glob.glob(‘
    .jpg’)

    currentTime = time.localtime()
    length = len(currentImageFiles)

    for i in currentFilelist:
                    if i == ‘backgroundslide.xml’:
                            os.remove(i)

    f = file(‘backgroundslide.xml’, ‘w’)

    f.write(‘<background>\n‘)
    f.write(‘\t<starttime>\n‘)
    f.write(‘\t\t<year>’ + str(currentTime.tm_year) + ‘</year>\n‘)
    f.write(‘\t\t<month>’ + str(currentTime.tm_mon) + ‘</month>\n‘)
    f.write(‘\t\t<day>’ + str(currentTime.tm_mday) + ‘</day>\n‘)
    f.write(‘\t\t<hour>’ + str(currentTime.tm_hour) + ‘</hour>\n‘)
    f.write(‘\t\t<minute>’ + str(currentTime.tm_min) + ‘</minute>\n‘)
    f.write(‘\t\t<second>’ + str(currentTime.tm_sec) + ‘</second>\n‘)
    f.write(‘\t</starttime>\n‘)
    f.write(‘<!–This animation will start at the time it created–>\n‘)

    for i in currentImageFiles:
            length = length – 1

            f.write(‘\t<static>\n‘)
            f.write(‘\t\t<duration>595.0</duration>\n‘)
            f.write(‘\t\t<file>’ + curdir + ‘/’ + currentImageFiles[length] +‘</file>\n‘)
            f.write(‘\t</static>\n‘)
            if length >= 1:
                    f.write(‘\t<transition>\n‘)
                    f.write(‘\t\t<duration>5.0</duration>\n‘)
                    f.write(‘\t\t<from>’ + curdir + ‘/’ + currentImageFiles[length] + ‘</from>\n‘)
                    f.write(‘\t\t<to>’ + curdir + ‘/’ + currentFilelist[length – 1] + ‘</to>\n‘)
                    f.write(‘\t</transition>\n‘)

    f.write(‘</background>\n‘)
    f.close()



      被我修改的如下:
    #!/usr/bin/env python
    # –– coding: utf-8 ––
    # Name: slidexml.py
    # Author: EthanZ6174
    # Email: <heracles.621@gmail.com>
    # Site: http://www.noslog.com
    # Licence: GPLv3
    # Version: 091127

    import glob, os
    import shutil
    import time

    curdir = os.getcwd()
    os.chdir(curdir)
    currentImageFiles = glob.glob(‘*.jpg’)

    currentTime = time.localtime()
    length = len(currentImageFiles)
    timeforwait = "10.0"
    timeforchange = "5.0"

    f = file(‘backgroundslide.xml’, ‘w’)

    f.write(‘<background>\n‘)
    f.write(‘\t<starttime>\n‘)
    f.write(‘\t\t<year>’ + str(currentTime.tm_year) + ‘</year>\n‘)
    f.write(‘\t\t<month>’ + str(currentTime.tm_mon) + ‘</month>\n‘)
    f.write(‘\t\t<day>’ + str(currentTime.tm_mday) + ‘</day>\n‘)
    f.write(‘\t\t<hour>’ + str(currentTime.tm_hour) + ‘</hour>\n‘)
    f.write(‘\t\t<minute>’ + str(currentTime.tm_min) + ‘</minute>\n‘)
    f.write(‘\t\t<second>’ + str(currentTime.tm_sec) + ‘</second>\n‘)
    f.write(‘\t</starttime>\n‘)
    f.write(‘<!–This animation will start at the time it created–>\n‘)

    for i in currentImageFiles:
            length = length – 1
            f.write(‘\t<static>\n‘)
            f.write(‘\t\t<duration>’+ timeforwait +‘</duration>\n‘)
            f.write(‘\t\t<file>’ + curdir + ‘/’ + currentImageFiles[length] +‘</file>\n‘)
            f.write(‘\t</static>\n‘)
            if length >= 1:
                    f.write(‘\t<transition>\n‘)
                    f.write(‘\t\t<duration>’ + timeforchange + ‘</duration>\n‘)
                    f.write(‘\t\t<from>’ + curdir + ‘/’ + currentImageFiles[length] + ‘</from>\n‘)
                    f.write(‘\t\t<to>’ + curdir + ‘/’ + currentImageFiles[length – 1] + ‘</to>\n‘)
                    f.write(‘\t</transition>\n‘)

    f.write(‘</background>\n‘)
    f.close()

  • 我的vimrc

      先简单地说一下自己的配置吧,首先就是直接使用的Vim系统附带的那个vimrc,然后把备份去掉了,但是和他的区别就是自己增加了几个自己比较常用的功能,自认为这些功能还不错,下面贴出来了。

      这里的话,我增加的命令是以’\’为前缀,暂时有以下几个:
      \html 自动生成html文件,将行号去除
      \clean 把文件清空
      \copy 将全文拷贝
      \ 自动格式化C文件
    if v:progname =~? "evim"
      finish
    endif

    set nocompatible

    set backspace=indent,eol,start

    map \html :w<Esc>:set nonu<Esc>:source $VIMRUNTIME/syntax/2html.vim<Esc>ZZZZ
    map \clean ggVGd
    map \copy ggVG"y
    map \ :w<Esc>:!indent "%:p" -kr -i8<Esc>
    set nu

    set history=50          " keep 50 lines of command line history
    set ruler               " show the cursor position all the time
    set showcmd             " display incomplete commands
    set incsearch           " do incremental searching

    " For Win32 GUI: remove ‘t’ flag from ‘guioptions’: no tearoff menu entries
    " let &guioptions = substitute(&guioptions, "t", "", "g")

    " Don’t use Ex mode, use Q for formatting
    map Q gq

    " CTRL-U in insert mode deletes a lot.  Use CTRL-G u to first break undo,
    " so that you can undo CTRL-U after inserting a line break.
    inoremap <C-U> <C-G>u<C-U>

    " In many terminal emulators the mouse works just fine, thus enable it.
    if has(‘mouse’)
      set mouse=a
    endif

    " Switch syntax highlighting on, when the terminal has colors
    " Also switch on highlighting the last used search pattern.
    if &t_Co > 2 || has("gui_running")
      syntax on
      set hlsearch
    endif

    " Only do this part when compiled with support for autocommands.
    if has("autocmd")

      " Enable file type detection.
      " Use the default filetype settings, so that mail gets ‘tw’ set to 72,
      " ‘cindent’ is on in C files, etc.
      " Also load indent files, to automatically do language-dependent indenting.
      filetype plugin indent on

      " Put these in an autocmd group, so that we can delete them easily.
      augroup vimrcEx
      au!

      " For all text files set ‘textwidth’ to 78 characters.
      autocmd FileType text setlocal textwidth=78

      " When editing a file, always jump to the last known cursor position.
      " Don’t do it when the position is invalid or when inside an event handler
      " (happens when dropping a file on gvim).
      " Also don’t do it when the mark is in the first line, that is the default
      " position when opening a file.
      autocmd BufReadPost 

        \ if line("’\"") > 1 && line("’\"") <= line("$") |
        \   exe "normal! g`\"" |
        \ endif

      augroup END

    else

      set autoindent                " always set autoindenting on

    endif " has("autocmd")

    " Convenient command to see the difference between the current buffer and the
    " file it was loaded from, thus the changes you made.
    " Only define it when not defined already.
    if !exists(":DiffOrig")
      command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
                      \ | wincmd p | diffthis
    endif

  • [转]mingw,cygwin,gnuwin32 的详细区别.

    • MinGW:Minimalist GNU for Windows
      • 安装MinGW
        • 无配置
      • 安装MSYS及MSYSDTK
        • 编辑了/MSYS.bat
          1. 加入chdir,使可以在目录外运行。
          2. 通过命令行参数%~dp0得到MSYS的路径。
          3. 删除其他命令行参数相关的动作。
          4. 将命令行参数%~dp1设置为环境变量MSYSINITDIR以备Shell初始目录之用。
          5. 将默认的Shell从rxvt改为sh。
        • 增加了/LoadMSYS.bat及/LoadMSYS.reg
          1. 作用:扩展命令行参数为完全路径名,将参数传送给MSYS.BAT。
          2. 将LoadMSYS.bat放在系统PATH下面,使在任何目录下都可以调用。
          3. 编辑注册表ROOT下面的*项和Folder项,以支持鼠标右健直接调用。
          4. 导出注册表项为LoadMSYS.reg,以备用。
        • 编辑了/etc/fstab
          1. 设置MinGW目录的Mount Point为/mingw
          2. 设置MINGW/INFO的Mount Point为/info
          3. 创建COMMAND目录,将Mount Point设为/usr/local/bin,以存放用MinGW Gcc编译的程序。
          4. 设置了其他一些常用目录的Mount Point。
        • 编辑了/etc/profile
          1. export PATH:加入/Mingw/bin。
          2. export INFOPATH:目录用;号隔开,作info搜索之用。
          3. 如果$MSYSINITDIR不为空,则改变为初始目录(CD之)。
        • 编辑了$HOME/.vimrc
          1. 配置复制自win32版的gvim。
          2. 加入syntax on:语法高亮。
          3. 加入set nu:显示行号。
          4. 加入set guifont:设置字体(console版本无效)
      • 总结
        • MinGW:许多unix源码,很难在不修改的情况下直接编译
        • MinGW:作为windows native programe(不依赖emulation layer),可以胜任
        • MSYS:对宽字符的支持较差
        • FREEWARE
    • Cygwin:GNU+Cygnus+Windows
      • 下载时只选择必需的程序包
      • 与MSYS近似的许多配置
      • 编辑了/etc/bash.bashrc
        • export PATH
        • export INFOPATH
          • 与MinGW不同,目录间用:号隔开
        • export MANPATH
      • 设置常用目录的Mount Point
        • Cygwin无/etc/fstab文件,Mount Point通过命令行mount命令设置,设置在下次重启之后仍有效。
      • 编译了新版本的Gcc及Gdb
      • 编译了新版本的make
      • 编译了termcap
      • 编译了less
      • 总结
        • 大多数unix源码都可以顺利编译
        • 对宽字符集支持较好
        • 编译的程序大多数依赖CygDLL
        • 非常丰富的程序库
        • FREEWARE
    • GnuWin32:Win32 ports of tools with a GNU or similar open source license
      • termcap
        • 在MSYS/MinGW环境下编译成功
      • less
        • 需要termcap
        • 在MSYS/MinGw环境下无法编译
          • 提示找不到langinfo.h
          • 下载了libgw32c的lib版,修改makefile,main.c,filename.c之后,编译成功,但运行时出现错误。 
        • 在Cygwin环境下编译成功
        • 用VC97编译成功
      • libgw32c
        • 在MSYS/MinGw环境下无法编译
          • 错误极多
        • 在Cygwin环境下无法编译
          • 错误极多
        • 连接bin版某些程序可以编译
          • 运行时出现错误
            1. 以编译less为例
      • wget
        • 用VC97编译成功
      • 总结
        • 源代码大多在MSYS/MinGW下无法成功编译
        • 源代码对Microsoft VC友好
        • 源代码对Cygwin/MinGW友好
        • 作为独立的工具程式较有价值
        • FREEWARE
    • 总结之总结
      • 这两三天,加上以前几天,仿佛很忙。./configure,make,make install,make clean,make distclean,info XXX,上网看文档,下载源代码。归结起来,没做什么有价值的事。就算积累了一些经验。经验不外是记忆,记忆不外是先进先出,然后完了。所以做了以上一点记号。哎,大脑内存不断磨损,还是复制到外存贮器上安全一点,算是备份。

  • NOIp 2005 提高组 1 谁拿了最多奖学金

      十分简单的题目,以前写过,以为是普及组里最垃圾的题目(普及组的水平都不算),就是算分然后判断,也没什么要注意的(对我来说要注意的就是我错过的地方,这个题目是少量的一次性AC的题目。),代码如下(比以前写的好看很多!):

    #include <stdio.h>
    struct pep{
            char name[21];
            int grade;
    };

    int getgrade(int a, int b, char c, char d, int e)
    {
            int n = 0;
            if(a > 80 && e > 0){
                    n += 8000;
            }
            if(a > 85 && b > 80){
                    n += 4000;
            }
            if(a > 90){
                    n += 2000;
            }
            if(a > 85 && d == ‘Y’){
                    n += 1000;
            }
            if(b > 80 && c == ‘Y’){
                    n += 850;
            }
            return n;
    }

    int main(void)
    {
            struct pep t, max;
            int a, b, e;
            char c, d;
            int n, i;
            int ans = 0;
            max.grade = 0;
            scanf("%d\n", &n);
            for(i = 0; i < n; i++){
                    scanf("%s %d %d %c %c %d\n", t.name, &a, &b, &c, &d, &e);
                    t.grade = getgrade(a, b, c, d, e);
                    ans += t.grade;
                    if(t.grade > max.grade){
                            max = t;
                    }
            }
            printf("%s\n%d\n%d\n", max.name, max.grade, ans);
            return 0;
    }

  • NOIp 2006 提高组 4 2^k进制数

      这题我以前写过的,现在就当是再温习一遍吧,思路就是递推(也就是动态规划)根据一个公式推导出来的DP方程,首先我用f[i][j]表示第i位数以j开头的数字共有多少个,那么最容易得到的一个转移方程是:
      f[i][j] = f[i – 1][j + 1] + f[i – 1][j + 2] + ……. + f[i – 1][n – 1] + f[i – 1][n].
      但是这个方程给我们的感觉就是一个字——太慢了,为什么这么慢呢?因为它就是这么慢,要把所有的一个个相加一次,但是注意到上面我画红的部分!就是用这个公式,这部分能够表示成啥?很简单啊:
      f[i][j + 1] = f[i – 1][j + 2] + ……. + f[i – 1][n – 1] + f[i – 1][n].
      那么智商高一点的人就看到玄机了,能够把f[i][j]简化成如下的形式:
      f[i][j] = f[i][j + 1] + f[i – 1][j + 1]
      如此一来程序就清晰多了,代码也很好写,要注意的是搜索时j是从后向前搜索,我还是使用面向对象的思想,先封装了一套int类型的,然后再修改成高精度类型的,int类型的(40分)如下:

    #include <stdio.h>
    typedef int num;
    num f[61][513];
    num ans;

    void give(num a, int b)
    {
            
    a = b;
    }

    void add(num a, num b)
    {
            a += b;
    }

    void output(num a)
    {
            printf("%d",
    a);
    }

    int main(void)
    {
            int i, j;
            int n, s, k, t, l;
            scanf("%d%d", &s, &n);
            k = 1 << s;
            for(i = 0; i < k; i++){
                    give(&f[0][i], 1);
            }
            t = n / s;
            for(i = 1; i <= t; i++){
                    for(j = k – i – 1; j >= 1; j–){
                            add(&f[i][j], &f[i][j + 1]);
                            add(&f[i][j], &f[i – 1][j + 1]);
                    }
            }
            for(i = 1; i < t; i++){
                    for(j = k – i – 1; j >= 1; j–){
                            add(&ans, &f[i][j]);
                    }
            }
            l = n – t s;
            if(l == 0){
                    l = k;
            }else{
                    l = 1 << l;
            }
            for(i = 1; i < l; i++){
                    add(&ans, &f[t][i]);
            }
            output(&ans);
            printf("\n");
            return 0;
    }
      详细修改了一番之后,发现主函数中错了,后来详细修改了一番,弄得我以为高精度写错了,仔细检查之后发现两个地方错了,第一个是数组开小了,本来是num f[61][513],后来发现要使用f[513][513],再一个就是不能够直接使用用(n – 1)/s,因为如果用30000/1(k = 1, w = 30000)的话那数组又会显得小了,需要f[30000][513],但是实际上又跟本用不到(因为k很小时最多只有
    !((1 << k) – 1)种情况,那样的情况很少)。
      所以最终修改了一大番,确定了AC代码:

    #include <math.h>
    #include <stdio.h>
    #define max(a, b) ((a)>(b)?(a):(b))
    #define used 100000000
    #define bits ((int)log10(used))
    #define MAX 26
    typedef struct{
            int num[MAX];
            int len;
    }num;
    num f[513][513];
    //数组开小了 
    num ans;

    void give(num a, int b)
    {
            int i;
            for(i = 0; b != 0; i++){
                    a->num[i] = b % used;
                    b /= used;
            }
            a->len = i;
    }

    void add(num a, num b)
    {
            int i;
            int len = max(a->len, b->len);
            int re = 0;
            for(i = 0; i < len; i++){
                    a->num[i] += b->num[i] + re;
                    re = a->num[i] / used;
                    a->num[i] %= used;
            }
            if(re > 0){
                    a->num[i] = re;
                    len++;
            }
            a->len = len;
    }

    void output(num a)
    {
            int i;
            int len = a->len,
    num = a->num;
            printf("%d", num[len – 1]);
            len–;
            for(i = len – 1; i >= 0; i–){
                    printf("%.*d", bits, num[i]);
            }
    }

    int main(void)
    {
            int i, j;
            int n, s, k, t, l;
            scanf("%d%d", &s, &n);
            k = 1 << s;
            t = (n – 1) / s + 1;
            if(t > k){                     //一直没写这个~!! 所以可能会出现各种想象不到的情况, 如:t = 3000
                    t = k;
            }
            for(i = 0; i < k; i++){
                    give(&f[0][i], 1);
            }
            for(i = 1; i < t; i++){
                    for(j = k – i – 1; j >= 1; j–){
                            add(&f[i][j], &f[i][j + 1]);
                            add(&f[i][j], &f[i – 1][j + 1]);
                    }
            }
            for(i = 1; i < t; i++){
                    for(j = k – i – 1; j >= 1; j–){
                            add(&ans, &f[i][j]);
                    }
            }
            l = n % s;
            if(l == 0){
                    l = k;
            }else{
                    l = 1 << l;
            }
            for(i = 1; i < l; i++){
                    add(&ans, &f[t – 1][i]);
            }
            output(&ans);
            printf("\n");
            return 0;
    }

  • Noip 2006 提高组 3 作业调度方案

      大部分OJ的题目全部都少了一些,原题见
      http://zqynux.blog.163.com/blog/static/167499597201062811365761/
      就是简单的贪心,但是要考虑的是首先,A任务的工序2必须在工序1之后完成,而且当满足前面一个条件时(工序2必须在工序1之后完成),尽可能的把任务向前面插:

    Noip 2006 提高组 3 作业调度方案 - NeWorldMaker - My S-K-Y
       代码如下:
    #include <stdio.h>
    #define max(a, b) ((a)>(b)?(a):(b))
    int order[361];
    int mch[19][19];
    int time[19][19];
    int count[19];
    int cpu[19][400];
    int used[19];
    int ans;

    int main(void)
    {
            int i, j, k, c, l;
            int m, n, t, s;
            scanf("%d%d", &m, &n);
            for(i = 0; i < m n; i++){
                    scanf("%d", &order[i]);
                    order[i]–;
            }
            for(i = 0; i < n; i++){
                    for(j = 0; j < m; j++){
                            //把n写成了m         
                            scanf("%d", &mch[i][j]);
                            mch[i][j]–;
                    }
            }
            for(i = 0; i < n; i++){
                    for(j = 0; j < m; j++){
                            //把n写成了m         
                            scanf("%d", &time[i][j]);
                    }
            }
            for(i = 0; i < m
    n; i++){
                    t = order[i];
                    s = count[t]++;
                    k = used[t];
                    while(1){
                            while(cpu[mch[t][s]][k]){
                                    k++;
                            }
                            c = 0;
                            while(cpu[mch[t][s]][k + c] == 0 && c < time[t][s]){
                                    c++;
                            }
                            if(c == time[t][s]){
                                    c = 0;
                                    while(c < time[t][s]){
                                            cpu[mch[t][s]][k + c] = 1;
                                            c++;
                                    }
                                    break;
                            }
                            k += c;
                    }
                    used[t] = k + time[t][s];
                    ans = max(ans, used[t]);
            }
            printf("%d\n", ans);
            return 0;
    }

  • NOIp 2006 提高组 2 金明的预算方案

      首先要考虑的是,如果没有主件和附件的话,那题目将会非常的简单,那这就是最简单的01背包了,但是麻烦的是题目有主件和附件。那我们怎么办呢?不做了?开玩笑,既然你走了OI这条路,那就千万别回头!那我能不能用01背包来处理这个题目呢?当然是能的,注意题目中的这句话“每个主件可以有0个、1个或2个附件。附件不再有从属于自己的附件。”额,这个条件有什么用呢?当然有用啦,那么我就可以转化为01背包了,先只考虑主件,那就可以进行01背包了,然后对每个主件进行记录,每个主件拥有多少个附件,哪些附件,然后再进行动态规划就能解决了。
      我把思路再整理一下,就是说先判断主件是否该买,如果它有一个附件的话,那么再考虑是否要购买这一个附件;如果有两个附件的话,那么就考虑是否购买第一个附件,第二个附件或者两个附件一起买(考虑他们的时候就一定要加上主件!)
      代码如下,提交了两次,问题出在一个符号上:

    #include <stdio.h>
    #define max(a, b) ((a)>(b)?(a):(b))
    struct thing{
            int priece, cost;
            struct {
                    int priece, cost;
            }sub[2];
            int len;
    }buy[60];
    int num[60];
    int len;
    int f[32001];

    int main(void)
    {
            int m, n;
            int i, j, k;
            int a, b, c;
            struct thing t;
            scanf("%d%d", &m, &n);
            for(i = 0; i < n; i++){
                    scanf("%d%d%d", &a, &b, &c);
                    if(c == 0){
                            num[len++] = i;
                            buy[i].priece = a
    b;
                            buy[i].cost = a;
                    }else{
                            t = &buy[c – 1];
                            t->sub[t->len].priece = a * b;
                            t->sub[t->len].cost = a;
                            t->len++;
                    }
            }
            for(i = 0; i < len; i++){
                    t = &buy[num[i]];
                    for(j = m; j >= t->cost; j–){
                            f[j] = max(f[j], f[j – t->cost] + t->priece);
                            for(k = 0; k < t->len; k++){
                                    if(j – t->cost – t->sub[k].cost >= 0){
                                            f[j] = max(f[j], f[j – t->cost – t->sub[k].cost] + t->priece + t->sub[k].priece);
                                    }
                            }
                            if(t->len == 2 && (j – t->cost – t->sub[0].cost – t->sub[1].cost >= 0)){
                                    f[j] = max(f[j], f[j – t->cost – t->sub[0].cost – t->sub[1].cost] + t->priece + t->sub[0].priece + t->sub[1].priece);
                                                    //把减法写成了加法,, 
                            }
                    }
            }
            printf("%d\n", f[m]);
            return 0;
    }

  • NOIP 2006 提高组 1 能量项链

      因为以前做过这一题,所以很快就写出来了,不过在一个细节的地方纠结了好久,具体位置见注释。
      思路和以前是一样的,f[i][j] = max(map[i] map[i + a] map[i + j] + f[i][a] + f[i + a][j – i]); f[i][j]表示从第i个珠子往后j个所能获得的最大能量,然后代码就写出来了:

    #include <stdio.h>
    int n;
    int map[200];
    unsigned f[100][101];

    void deal(int a, int b)
    {
            int i;
            unsigned max = 0, t;
            for(i = 1; i < b; i++){
                    t = map[a] map[a + i] map[a + b]
                                            //这里的a+b写成了a + i + 1
                            + f[a][i] + f[(a + i) % n][b – i];
                    if(t > max){
                            max = t;
                    }
            }
            f[a][b] = max;
    }

    int main(void)
    {
            int i, j;
            unsigned max;
    //      freopen("abc.txt", "r", stdin);
            scanf("%d", &n);
            for(i = 0; i < n; i++){
                    scanf("%d", &map[i]);
                    map[i + n] = map[i];
            }
            for(j = 2; j <= n; j++){
                    for(i = 0; i < n; i++){
                            deal(i, j);
                    }
            }
            max = 0;
            for(i = 0; i < n; i++){
                    if(max < f[i][n]){
                            max = f[i][n];
                    }
            }
            printf("%d\n", max);
    //      getch();
            return 0;
    }

  • NOIp 2007 提高组 4 树网的核

      这个题目网上有很多题解,不过直接照抄的话确实不太好,我还是说说我自己的过程吧。
      首先,可以知道的是“核”越长越好,确实说不太清楚,看下面的图吧:

    NOIp 2007 提高组 4 树网的核 - NeWorldMaker - My S-K-Y
       如果核是A-B的话,A-B距离X的值为B到X的距离,假设为x,即B至X的距离,但是如果核是A-C的话,那么A-C距离X的值就会小于x,所以“核”还是越长越好!
      后只需要从一条直径上寻找核就可以了,为什么的话,我觉得吧,最好的“核”选择有两点,第一点如上所述,越长越好;我觉得第二点就是越靠近中点越好,至于为什么的话,你自己想想,中点距离所有点的最长距离就是半径,而重点之外的就会大于半径,那么不就是长了?所以的话还是越靠近中点越好,所以从一条直径搜索应该是够了的(我知道这样解释是行不通的,但是我自己也不知道是什么原因,只好这么说了。)
      直径的寻找就是随意使用一个点寻找最远的距离的节点,这就是一条直径的一端,然后从最远距离的节点出发再寻找一次最远距离,这就构成了一条直径,至于为什么,距离一个节点最远的距离为什么一定是一条直径的一端,我的理解是距离一个节点最远的距离一定是距离中点的距离加上半径的长度,也就是说最远的距离是先经过中点再去寻找半径。
      寻找到了半径再根据s求枚举所有的核的可能,这里要注意的一点就是(我烦的错误),寻找d(F, V)的时候是先取距离整条边最长的节点,然后取所有边(核)中最小的一个。
      代码附上:
    #include <stdio.h>
    #include <string.h>
    #define bzero(a, b) memset((a), 0, (b))
    int n, s;
    int map[300][300];

    int ans = 10000000;

    int used[300];
    int prev[300];
    int dist[300];
    int max, loc;

    void d(int i, int sum)
    {
            int j;
            used[i] = 1;
            if(sum > max){
                    loc = i;
                    max = sum;
            }
            for(j = 0; j < n; j++){
                    if(!used[j] && map[i][j]){
                            dist[j] = sum + map[i][j];
                            prev[j] = i;
                            d(j, dist[j]);
                    }
            }
    }

    void dfs(int node)
    {
            bzero(used, sizeof(used));
            bzero(prev, sizeof(prev));
            bzero(dist, sizeof(dist));
            max = 0;
            prev[node] = –1;
            d(node, 0);
    }

    int lis[300];
    int lenth;

    void find(void)
    {
            int i;
            dfs(0);
            dfs(loc);
            i = loc;
            while(i != –1){
                    lis[lenth++] = i;
                    i = prev[i];
            }
    }

    int tmp[90000];

    //先删除本路径, 再逐个dfs,, 再恢复路径 
    void deal(int a, int b)
    {
            int i, m;
            //删除本路劲 
            for(i = a; i < b; i++){
                    tmp[i – a] = map[lis[i]][lis[i + 1]];
                    map[lis[i]][lis[i + 1]] = 0;
                    map[lis[i + 1]][lis[i]] = 0;
            }
            //获取距离本路径最远的距离
            m = 0;
            for(i = a; i <= b; i++){
                    dfs(lis[i]);
                    if(m < max){
                            m = max;
                    }
            }
            //更新ans 
            if(ans > m){
                    ans = m;
            }
            //恢复路径 
            for(i = a; i < b; i++){
                    map[lis[i]][lis[i + 1]] = tmp[i – a];
                    map[lis[i + 1]][lis[i]] = tmp[i – a];
            }
    }

    void work(void)
    {
            int i, j;
            int d;
            for(i = 0; i < lenth; i++){
                    //寻找尽可能长的核 
                    d = map[lis[i]][lis[i + 1]];
                    for(j = i + 1; j < lenth && d <= s; j++){ 
                            d += map[lis[j]][lis[j + 1]];
                    }
                    //获取此核的长度, 并更新ans 
                    deal(i, j – 1);
            }
    }

    int main(void)
    {
            int i;
            int a, b, c;
            scanf("%d%d", &n, &s);
            for(i = 1; i < n; i++){
                    scanf("%d%d%d", &a, &b, &c);
                    a–, b–;
                    map[a][b] = map[b][a] = c;
            }
            //寻找半径,, 然后用lis数组记录半径的线路 
            find();
            //寻找最小的偏心距,,  用ans记录 
            work();
            printf("%d\n", ans);
            return 0;
    }