分类: 技术

  • USACO 2.4 Fractions to Decimals 分数化小数 解题报告

    Fractions to Decimals

    Write a program that will accept a fraction of the form N/D, where N is the numerator and D is the denominator and print the decimal representation. If the decimal representation has a repeating sequence of digits, indicate the sequence by enclosing it in brackets. For example, 1/3 = .33333333…is denoted as 0.(3), and 41/333 = 0.123123123…is denoted as 0.(123). Use xxx.0 to denote an integer. Typical conversions are:

    1/3     =  0.(3)
    22/5    =  4.4
    1/7     =  0.(142857)
    2/2     =  1.0
    3/8     =  0.375
    45/56   =  0.803(571428)

    PROGRAM NAME: fracdec
    INPUT FORMAT
    A single line with two space separated integers, N and D, 1 <= N,D <= 100000.
    SAMPLE INPUT (file fracdec.in)
    45 56

    OUTPUT FORMAT
    The decimal expansion, as detailed above. If the expansion exceeds 76 characters in length, print it on multiple lines with 76 characters per line.
    SAMPLE OUTPUT (file fracdec.out)
    0.803(571428)

    描述
    写一个程序,输入一个形如N/D的分数(N是分子,D是分母),输出它的小数形式。如果小数有循环节的话,把循环节放在一对圆括号中。

    例如, 1/3 =0.33333333 写成0.(3), 41/333 = 0.123123123… 写成0.(123), 用xxx.0 等表示整数。典型的转化例子:

    1/3 = 0.(3)
    22/5 = 4.4
    1/7 = 0.(142857)
    2/2 = 1.0
    3/8 = 0.375
    45/56 = 0.803(571428)
    PROGRAM NAME
    fracdec

    INPUT FORMAT
    单独的一行包括被空格分开的N和D(1 <= N,D <= 100000)。

    SAMPLE INPUT
    (file fracdec.in)

    45 56
    OUTPUT FORMAT
    按照上面规则计算出的小数表达式.如果结果长度大于76,每行输出76个字符.




    SAMPLE OUTPUT
    (file fracdec.out)

    0.803(571428)



    ======================== 华丽的分割线 ========================
      这道题我不好怎么说, 看了标程写的,, 思路比较简单, 只是这种题目重来没做过, 所以不知道怎么下手..
      如果余数相等的话, 那么就已经循环了,, 我用rem来存储余数和非循环小数的个数..

    /*
    LANG: C
    ID: zqy11001
    PROG: fracdec
    */
    #include <stdio.h>
    #define MAX 100010
    #define getint(i) scanf(%d, &i)
    
    int rm[MAX];
    char buf[MAX];
    char dev[MAX];
    int counter;
    
    int main(void)
    {
     int m, n;
     int i, j;
     freopen(fracdec.in, r, stdin);
     freopen(fracdec.out, w, stdout);
     getint(m);
     getint(n);
     sprintf(buf, %d., m/n);
     memset(rm, -1, sizeof(rm));
     m = m % n;
     dev[0] = \'0\';
     for(i = 0; ; i++){
     if(m == 0){
     sprintf(buf + strlen(buf), %s, dev);
     break;
     }
     if(rm[m] != -1){
     sprintf(buf + strlen(buf), %.*s(%s), rm[m], 
     dev, dev + rm[m]);
     break;
     }
     rm[m] = i;
     m *= 10;
     dev[counter++] = m / n + \'0\';
     m = m % n;
    
     }
    
     for(i = 0; i < strlen(buf); i+=76){
     printf(%.76s\\n, buf + i);
     }
     return 0;
    }
  • USACO 2.4 Bessie Come Home 回家 解题报告

    Bessie Come Home
    Kolstad & Burch
    It’s dinner time, and the cows are out in their separate pastures. Farmer John rings the bell so they will start walking to the barn. Your job is to figure out which one cow gets to the barn first (the supplied test data will always have exactly one fastest cow).

    Between milkings, each cow is located in her own pasture, though some pastures have no cows in them. Each pasture is connected by a path to one or more other pastures (potentially including itself). Sometimes, two (potentially self-same) pastures are connected by more than one path. One or more of the pastures has a path to the barn. Thus, all cows have a path to the barn and they always know the shortest path. Of course, cows can go either direction on a path and they all walk at the same speed.

    The pastures are labeled ‘a’..’z’ and ‘A’..’Y’. One cow is in each pasture labeled with a capital letter. No cow is in a pasture labeled with a lower case letter. The barn’s label is `Z’; no cows are in the barn, though.

    PROGRAM NAME: comehome
    INPUT FORMAT
    Line 1:  Integer P (1 <= P <= 10000) the number of paths that interconnect the pastures (and the barn) 
    Line 2..P+1:  Space separated, two letters and an integer: the names of the interconnected pastures/barn and the distance between them (1 <= distance <= 1000) 

    SAMPLE INPUT (file comehome.in)
    5
    A d 6
    B d 3
    C e 9
    d Z 8
    e Z 3

    OUTPUT FORMAT
    A single line containing two items: the capital letter name of the pasture of the cow that arrives first back at the barn, the length of the path followed by that cow.
    SAMPLE OUTPUT (file comehome.out)
    B 11

    描述
    现在是晚餐时间,而母牛们在外面分散的牧场中。农民约翰按响了电铃,所以她们开始向谷仓走去。你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只速度最快的母牛)。在挤奶的时候(晚餐前),每只母牛都在她自己的牧场上,一些牧场上可能没有母牛。每个牧场由一条条道路和一个或多个牧场连接(可能包括自己)。有时,两个牧场(可能是字母相同的)之间会有超过一条道路相连。至少有一个牧场和谷仓之间有道路连接。因此,所有的母牛最后都能到达谷仓,并且母牛总是走最短的路径。当然,母牛能向着任意一方向前进,并且她们以相同的速度前进。牧场被标记为’a’..’z’和’A’..’Y’,在用大写字母表示的牧场中有一只母牛,小写字母中则没有。谷仓的标记是’Z’,注意没有母牛在谷仓中。


    注意’m’和’M’不是一个牧场 否则错误

    格式
    PROGRAM NAME: comehome

    INPUT FORMAT

    第 1 行: 整数 P(1<= P<=10000),表示连接牧场(谷仓)的道路的数目。

    第 2 ..P+1行: 用空格分开的两个字母和一个整数:

    被道路连接牧场的标记和道路的长度(1<=长度<=1000)。

    SAMPLE INPUT
    (file comehome.in)

    5
    A d 6
    B d 3
    C e 9
    d Z 8
    e Z 3
    OUTPUT FORMAT

    单独的一行包含二个项目: 最先到达谷仓的母牛所在的牧场的标记,和这只母牛走过的路径的长度。

    SAMPLE OUTPUT
    (file comehome.out)

    B 11


    ========================= 华丽的分割线 =========================
      这题是自己独立完成的,, 喜一个(以前的话都是看着提示和标程之后完成的..)
      思路的话和上一题的思路差不多,,
    http://zqynux.javaeye.com/blog/626000
      所以这方面我就不怎么说明了, 不过这个题目我从一开始就觉得奇怪, n的上限怎么是10000,, 不过没想太多, 就开始写了…, 写完提交试试,, 没AC,, 看了看数据, 和Z有关的只有一个Z a 100, 才想到这是一个无向带权的图, 稍加修改之后又被卡住了,, 到网上看了一下分析才想起来,, 题目里有这么一句话: "两个牧场(可能是字母相同的)之间会有超过一条道路相连。",, 而我们需要的只是最短的,, 所以我又修改了一下…
      也就是说这个10000是有意义的~! 哈,, 还是怪自己审题不清楚..

    /*
    LANG: C
    ID: zqy11001
    PROG: comehome
    */
    #include <stdio.h>
    #define getint(i) scanf(%d\\n, &i)
    #define getmark(a, i) if(i >= \'A\' && i <= \'Z\'){\\
     a = 26 + i - \'A\';\\
     }else{\\
     a = i - \'a\';\\
     }
    #define MAX 52
    #define INF (1e9)
    
    int map[MAX][MAX];
    int n;
    
    void mark(char i, char j, int t)
    {
     int a, b;
     getmark(a, i);
     getmark(b, j);
     if(map[a][b] != 0){
     if(t < map[a][b]){
     map[a][b] = t;
     map[b][a] = t; 
     }
     return ;
     }
     map[a][b] = t;
     map[b][a] = t;
    }
    
    int main(void)
    {
     int i, j, k, t;
     int min = INF, m;
     char a, b;
     freopen(comehome.in, r, stdin);
     freopen(comehome.out, w, stdout);
     getint(n);
     for(i = 0; i < n; i++){
     scanf(%c %c %d\\n, &a, &b, &t);
     mark(a, b, t);
     }
     for(i = 0; i < MAX; i++){
     for(j = 0; j < MAX; j++){
     if(map[i][j] == 0 && i != j){
     map[i][j] = INF;
     }
     }
     }
    
     for(k = 0; k < MAX; k++)
     for(i = 0; i < MAX; i++)
     for(j = 0; j < MAX; j++){
     if(map[i][j] > map[i][k] + map[k][j]){
     map[i][j] = map[i][k] + map[k][j];
     map[j][i] = map[i][k] + map[k][j];
     }
     }
    
     for(i = 26; i < MAX - 1; i++){
     if(map[i][51] < min && map[i][51] != 0){
     min = map[i][51];
     m = i;
     }
     }
    
     printf(%c %d\\n, m - 26 + \'A\', min);
     return 0;
    }
  • USACO Longest Prefix最长前缀 解题报告

    Longest Prefix
    IOI’96
    The structure of some biological objects is represented by the sequence of their constituents denoted by uppercase letters. Biologists are interested in decomposing a long sequence into shorter ones called primitives.

    We say that a sequence S can be composed from a given set of primitives P if there is a some sequence of (possibly repeated) primitives from the set whose concatenation equals S. Not necessarily all primitives need be present. For instance the sequence ABABACABAABcan be composed from the set of primitives

       {A, AB, BA, CA, BBC}

    The first K characters of S are the prefix of S with length K. Write a program which accepts as input a set of primitives and a sequence of constituents and then computes the length of the longest prefix that can be composed from primitives.

    PROGRAM NAME: prefix
    INPUT FORMAT
    First, the input file contains the list (length 1..200) of primitives (length 1..10) expressed as a series of space-separated strings of upper-case characters on one or more lines. The list of primitives is terminated by a line that contains nothing more than a period (‘.’). No primitive appears twice in the list. Then, the input file contains a sequence S (length 1..200,000) expressed as one or more lines, none of which exceed 76 letters in length. The "newlines" are not part of the string S.
    SAMPLE INPUT (file prefix.in)
    A AB BA CA BBC
    .
    ABABACABAABC

    OUTPUT FORMAT
    A single line containing an integer that is the length of the longest prefix that can be composed from the set P.
    SAMPLE OUTPUT (file prefix.out)
    11

    描述
    在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的。生物学家对于把长的序列分解成较短的(称之为元素的)序列很感兴趣。

    如果一个集合 P 中的元素可以通过串联(允许重复;串联,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素。并不是所有的元素都必须出现。举个例子,序列 ABABACABAAB 可以分解为下面集合中的元素:

    {A, AB, BA, CA, BBC}

    序列 S 的前面 K 个字符称作 S 中长度为 K 的前缀。设计一个程序,输入一个元素集合以及一个大写字母序列,计算这个序列中(由集合元素组成的)最长的前缀的长度。

    格式
    PROGRAM NAME: prefix

    INPUT FORMAT

    输入数据的开头包括 1..200 个元素(长度为 1..10 )组成的集合,用连续的以空格分开的字符串表示。字母全部是大写,数据可能不止一行。元素集合结束的标志是一个只包含一个 “.” 的行。集合中的元素没有重复。接着是大写字母序列 S ,长度为 1..200,000 ,用一行或者多行的字符串来表示,每行不超过 76 个字符。换行符并不是序列 S 的一部分。

    OUTPUT FORMAT

    只有一行,输出一个整数,表示 S 能够分解成 P 中元素的最长前缀的长度。

    SAMPLE INPUT (file prefix.in)
    A AB BA CA BBC
    .
    ABABACABAABC
    SAMPLE OUTPUT (file prefix.out)
    11


    ============================ 华丽的分割线 ============================
      前两天写出来了,, 忘记发日志了`
      感觉用的这个方法不像是DP(对于DP我还没有特别清楚的概念..),, 其中pre变量存储所有的匹配串(即短的那个字符串.), str是住串(长的那个.), 接下来最关键的是lenth这个变量,, (感觉名字没取好), 这个主串假设分为分为a1 a2 a3 … an, lenth[i]如果是1的话代表在a1 a2 a3 .. ai 都是能够在匹配串匹配..
      说了一些云里雾里的话吧,, 废话不多,, 代码上:

    /*
    LANG: C
    ID: zqy11001
    PROG: prefix
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define getstr(s) scanf(%s, s)
    char pre[401][11];
    int m;
    
    char lenth[200001];
    char str[200000];
    int n;
    
    int main(void)
    {
     int i, j, k;
     int best = 0;
     freopen(prefix.in, r, stdin);
     freopen(prefix.out, w, stdout);
     while(1){
     getstr(pre[m]);
     if(pre[m][0] == \'.\'){
     break;
     }
     m++;
     }
     while(getstr(str + n) == 1){
     n += strlen(str + n);
     }
     lenth[0] = 1;
     best = 0;
     for(i = 0; i < n; i++){
     if(lenth[i]){
     best = i;
     for(j = 0; j < m; j++){
     for(k = 0; ((i + k) < n) && (pre[j][k] != \'\\0\') && 
     (pre[j][k] == str[i + k]); k++){
     ;
     }
     if(pre[j][k] == \'\\0\'){
     lenth[i + k] = 1;
     }
     }
     }
     }
     if (lenth[n])
     best = n;
     printf(%d\\n, best);
     return 0;
    }
  • USACO 2.3 Zero Sum 零的算式和 解题报告

    Zero Sum

    Consider the sequence of digits from 1 through N (where N=9) in increasing order: 1 2 3 … N.

    Now insert either a ‘+’ for addition or a ‘-‘ for subtraction or a ‘ ‘ [blank] to run the digits together between each pair of digits (not in front of the first digit). Calculate the result that of the expression and see if you get zero.

    Write a program that will find all sequences of length N that produce a zero sum.

    PROGRAM NAME: zerosum
    INPUT FORMAT
    A single line with the integer N (3 <= N <= 9).
    SAMPLE INPUT (file zerosum.in)
    7

    OUTPUT FORMAT
    In ASCII order, show each sequence that can create 0 sum with a ‘+’, ‘-‘, or ‘ ‘ between each pair of numbers.
    SAMPLE OUTPUT (file zerosum.out)
    1+2-3+4-5-6+7
    1+2-3-4+5+6-7
    1-2 3+4+5+6+7
    1-2 3-4 5+6 7
    1-2+3+4-5+6-7
    1-2-3-4-5+6+7


    USACO_2.3-3:zerosum零的算式和

    Time Limit:1000MS  Memory Limit:65536K
    Total Submit:6 Accepted:4

    Description

    请考虑一个由1到N(N=3, 4, 5 … 9)的数字组成的递增数列:1 2 3 … N。现在请在数列中插入“+”表示加,或者“-”表示减,抑或是“ ”表示空白,来将每一对数字组合在一起(请不在第一个数字前插入符号)。计算该表达式的结果并注意你是否得到了和为零。请你写一个程序找出所有产生和为零的长度为N的数列。

    Input

    PROGRAM NAME: zerosum

    单独的一行表示整数N (3 <= N <= 9)。


    Output

    按照ASCII码的顺序,输出所有在每对数字间插入“+”, “-”, 或 “ ”后能得到和为零的数列。

    Sample Input


    7

    Sample Output


    1+2-3+4-5-6+7
    1+2-3-4+5+6-7
    1-2 3+4+5+6+7
    1-2 3-4 5+6 7
    1-2+3+4-5+6-7
    1-2-3-4-5+6+7

    ========================= 华丽的分割线 =========================
      一个DFS, 题目说了按ASCII的顺序进行输出, 也就是先’ ‘, 再’+’, 接着’-‘.., 我拿到题目就写了一个程序,, DFS没写错, 就是算和的时候错了. 试着写了几个版本, 都错了..(看样子我还是不怎么滴啊~~ 狂汗”).
      不说多的废话了, 代码贴上来:

    /*
    LANG: C
    ID: zqy11001
    PROG: zerosum
    */
    #include <stdio.h>
    #define getint(i) scanf(%d, &i)
    #define putint(i) printf(%d, i)
    #define ze(now, c) str[now] = c; zero(now + 1);
    #define MAX 200
    
    int n;
    char str[9];
    
    void out(void)
    {
     int i;
     putchar(\'1\');
     for(i = 1; i < n; i++){
     printf(%c%d, str[i], i + 1);
     }
     putchar(\'\\n\');
    }
    
    void zero(int sum, int t, int now, char s)
    {
     if(now == n){
     if(s == \'+\'){
     sum += t;
     }else{
     sum -= t;
     }
     if(sum == 0 && str[0] == \'+\'){
     out();
     }
     return;
     }
     str[now] = \' \';
     zero(sum, t * 10 + now + 1, now + 1, s);
     if(s == \'+\'){
     sum += t;
     }else{
     sum -= t;
     }
     str[now] = \'+\';
     zero(sum, now + 1, now + 1, \'+\');
     str[now] = \'-\';
     zero(sum, now + 1, now + 1, \'-\');
    }
    
    int main(void)
    {
     int i, j;
     freopen(zerosum.in, r, stdin);
     freopen(zerosum.out, w, stdout);
     getint(n);
     zero(0, 0, 0, \'+\');
     return 0;
    }
  • USACO 2.3 Cow Pedigrees 奶牛家谱 解题报告

    Farmer John is considering purchasing a new herd of cows. In this new herd, each mother cow gives birth to two children. The relationships among the cows can easily be represented by one or more binary trees with a total of N (3 <= N < 200) nodes. The trees have these properties:

    The degree of each node is 0 or 2. The degree is the count of the node’s immediate children.
    The height of the tree is equal to K (1 < K <100). The height is the number of nodes on the longest path from the root to any leaf; a leaf is a node with no children.
    How many different possible pedigree structures are there? A pedigree is different if its tree structure differs from that of another pedigree. Output the remainder when the total number of different possible pedigrees is divided by 9901.

    PROGRAM NAME: nocows
    INPUT FORMAT
    Line 1: Two space-separated integers, N and K.
    SAMPLE INPUT (file nocows.in)
    5 3

    OUTPUT FORMAT
    Line 1: One single integer number representing the number of possible pedigrees MODULO 9901.
    SAMPLE OUTPUT (file nocows.out)
    2

    OUTPUT DETAILS
    Two possible pedigrees have 5 nodes and height equal to 3:
               @                   @     
              / \                 / \
             @   @      and      @   @
            / \                     / \
           @   @                   @   @



    USACO_2.3-2:Cow Pedigrees奶牛家谱

    Time Limit:1000MS  Memory Limit:65536K
    Total Submit:1 Accepted:1

    Description

    农民约翰准备购买一群新奶牛。 在这个新的奶牛群中, 每一个母亲奶牛都生两小奶牛。这些奶牛间的关系可以用二叉树来表示。这些二叉树总共有N个节点(3 <= N < 200)。这些二叉树有如下性质:

    每一个节点的度是0或2。度是这个节点的孩子的数目。

    树的高度等于K(1 < K < 100)。高度是从根到任何叶子的最长的路径上的节点的数目; 叶子是指没有孩子的节点。

    有多少不同的家谱结构? 如果一个家谱的树结构不同于另一个的, 那么这两个家谱就是不同的。输出可能的家谱树的个数除以9901的余数。

    Input

    PROGRAM NAME: nocows

    第1行: 两个空格分开的整数, N和K。

    Output

    第 1 行: 一个整数,表示可能的家谱树的个数除以9901的余数。

    Sample Input


    SAMPLE INPUT (file nocows.in)

    5 3

    Sample Output


    SAMPLE OUTPUT (file nocows.out)

    2


    ======================== 华丽的分割线 ========================
      题目是看懂了,, 意思就是说用N个节点构造一个高度为K的二叉树, 且每个节点的度不能为1(即只能要么有两个儿子, 要么就没有没有孩子.), 题目我是理解了, 也清楚得很是用DP.. 但是不太会做.. DP没学好.. (自卑中)
      终于吧DP返程看懂了.~!~!~! 狂High中..
      f[i][j] 代表用i各节点构成最多j层的二叉树有多少种情况, 那么
      f[i][j] = ∑(f[m][j-1] * f[i-1-m][j-1])(m = 1, 2, 3 … i – 1)
      m是左子树的节点个数,, 那么i – m 就是除了左子树节点个数之外的节点个数, 再除根节点, 即 i – m – 1就是右子树的节点个数..
      代码能有两个优化的地方(我能够想到的只有这两个),
      第一个就是在DP方程中f[i][j] 和 f[m][j] 都一定是奇数, 因为如果是偶数的话就不能够构成题目所要求的二叉树了.
      第二个就是数据是能够对折的. 这个我晚点尝试一下.. 现在先把没折半的发一下吧.

    /*
    PROG: nocows
    ID: zqy11001
    LANG: C
    */
    #include <stdio.h>
    
    int f[200][100];
    
    int main(void)
    {
     int n, m;
     int i, j, k;
     freopen(nocows.in, r, stdin);
     freopen(nocows.out, w, stdout);
     scanf(%d%d, &n, &m);
     for(j = 1; j <= m; j++){
     f[1][j] = 1;
     }
     for(j = 2; j <= m; j++){
     for(i = 1; i <= n; i += 2){
     for(k = 1; k <= i - 2; k++){
     f[i][j] += f[k][j - 1] * f[i - k - 1][j - 1];
     f[i][j] %= 9901;
     }
     }
     }
     printf(%d\\n, (9901 + f[n][m] - f[n][m - 1]) % 9901);
     return 0;
    }
  • USACO 2.3 Money Systems 货币系统 解题报告

    Money Systems

    The cows have not only created their own government but they have chosen to create their own money system. In their own rebellious way, they are curious about values of coinage. Traditionally, coins come in values like 1, 5, 10, 20 or 25, 50, and 100 units, sometimes with a 2 unit coin thrown in for good measure.

    The cows want to know how many different ways it is possible to dispense a certain amount of money using various coin systems. For instance, using a system of {1, 2, 5, 10, …} it is possible to create 18 units several different ways, including: 18×1, 9×2, 8×2+2×1, 3×5+2+1, and many others.

    Write a program to compute how many ways to construct a given amount of money using supplied coinage. It is guaranteed that the total will fit into both a signed long long (C/C++) and Int64 (Free Pascal).

    PROGRAM NAME: money
    INPUT FORMAT
    The number of coins in the system is V (1 <= V <= 25).

    The amount money to construct is N (1 <= N <= 10,000). Line 1:  Two integers, V and N 
    Lines 2..:  V integers that represent the available coins (no particular number of integers per line)


    SAMPLE INPUT (file money.in)
    3 10
    1 2 5

    OUTPUT FORMAT
    A single line containing the total number of ways to construct N money units using V coins.
    SAMPLE OUTPUT (file money.out)
    10


    描述
    母牛们不但创建了他们自己的政府而且选择了建立了自己的货币系统。由于他们特殊的思考方式,他们对货币的数值感到好奇。

    传统地,一个货币系统是由1,5,10,20 或 25,50, 和 100的单位面值组成的。

    母牛想知道有多少种不同的方法来用货币系统中的货币来构造一个确定的数值。

    举例来说, 使用一个货币系统 {1,2,5,10,…}产生 18单位面值的一些可能的方法是:18×1, 9×2, 8×2+2×1, 3×5+2+1,等等其它。写一个程序来计算有多少种方法用给定的货币系统来构造一定数量的面值。保证总数将会适合long long (C/C++) 和 Int64 (Free Pascal),即在0 到2^63-1之间。

    格式
    PROGRAM NAME: money

    INPUT FORMAT:

    (file money.in)

    货币系统中货币的种类数目是 V (1<= V<=25)。要构造的数量钱是 N (1<= N<=10,000)。

    第 1 行: 二整数,V 和 N 。

    第 2 行: 可用的货币的面值 。

    OUTPUT FORMAT:

    (file money.out)

    单独的一行包含那个可能的用这v种硬币凑足n单位货币的方案数。

    SAMPLE INPUT
    3 10
    1 2 5
    SAMPLE OUTPUT
    10

    ======================= 华丽的分割线 =======================

      看到这题就知道又是最复杂, 最有用的DP问题..(天啊!DP我怎么还没开窍?)
      dp方程:
      f[j] 代表构造价值为j的方法有多少种`?
      f[j] += f[j – c[i]]
      DP我真的不会解释,, 下次把背包九讲仔细看下!!!
      先把代码上上吧~

    /*
    LANG: C
    ID: zqy11001
    PROG: money
    */
    #include <stdio.h>
    #define getint(i) scanf(%d, &i)
    
    long long f[10001];
    
    int main(void)
    {
     int n, m;
     int i, j, k, t;
     freopen(money.in, r, stdin);
     freopen(money.out, w, stdout);
     getint(n);
     getint(m);
     f[0] = 1;
     for(i = 1; i <= n; i++){
     getint(t);
     for(j = t; j <= m; j++){
     f[j] += f[j - t];
     }
     }
     printf(%lld\\n, f[m]);
     return 0;
    }
  • USACO 1.1 Broken Necklace 破碎的项链 解题报告

    Broken Necklace
    You have a necklace of N red, white, or blue beads (3<=N<=350) some of which are red, others blue, and others white, arranged at random. Here are two examples for n=29:

                    1 2                               1 2
                r b b r                           b r r b
              r         b                       b         b
             r           r                     b           r
            r             r                   w             r
           b               r                 w               w
          b                 b               r                 r
          b                 b               b                 b
          b                 b               r                 b
           r               r                 b               r
            b             r                   r             r
             b           r                     r           r
               r       r                         r       b
                 r b r                             r r w
                Figure A                         Figure B
                            r red bead
                            b blue bead
                            w white bead

    The beads considered first and second in the text that follows have been marked in the picture.

    The configuration in Figure A may be represented as a string of b’s and r’s, where b represents a blue bead and r represents a red one, as follows: brbrrrbbbrrrrrbrrbbrbbbbrrrrb .

    Suppose you are to break the necklace at some point, lay it out straight, and then collect beads of the same color from one end until you reach a bead of a different color, and do the same for the other end (which might not be of the same color as the beads collected before this).

    Determine the point where the necklace should be broken so that the most number of beads can be collected.

    Example
    For example, for the necklace in Figure A, 8 beads can be collected, with the breaking point either between bead 9 and bead 10 or else between bead 24 and bead 25.

    In some necklaces, white beads had been included as shown in Figure B above. When collecting beads, a white bead that is encountered may be treated as either red or blue and then painted with the desired color. The string that represents this configuration will include the three symbols r, b and w.

    Write a program to determine the largest number of beads that can be collected from a supplied necklace.

    PROGRAM NAME: beads
    INPUT FORMAT
    Line 1:  N, the number of beads
    Line 2:  a string of N characters, each of which is r, b, or w

    SAMPLE INPUT (file beads.in)
    29
    wwwbbrwrbrbrrbrbrwrwwrbwrwrrb

    OUTPUT FORMAT
    A single line containing the maximum of number of beads that can be collected from the supplied necklace.
    SAMPLE OUTPUT (file beads.out)
    11

    OUTPUT EXPLANATION
    Consider two copies of the beads (kind of like being able to runaround the ends). The string of 11 is marked.
    wwwbbrwrbrbrrbrbrwrwwrbwrwrrb wwwbbrwrbrbrrbrbrwrwwrbwrwrrb
                           ** *****


    题目描述
        你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的。 这里是 n=29 的二个
    例子:



                   1 2                               1 2
               r b b r                           b r r b
             r         b                       b         b
            r           r                     b           r
           r             r                   w             r
          b               r                 w               w
         b                 b               r                 r
         b                 b               b                 b
         b                 b               r                 b
          r               r                 b               r
           b             r                   r             r
            b           r                     r           r
              r       r                         r       b
                r b r                             r r w
                图片 A                        图片  B
                   
                            r 代表 红色的珠子     
                                b 代表 蓝色的珠子  
                                w 代表 白色的珠子
    第一和第二个珠子在图片中已经被作记号。
    图片 A 中的项链可以用下面的字符串表示:

    brbrrrbbbrrrrrbrrbbrbbbbrrrrb .
        假如你要在一些点打破项链,展开成一条直线,然后从一端开始收集同颜色的珠子直到你遇到一个不同的颜色珠子,在
    另一端做同样的事(颜色可能与在这之前收集的不同)。 确定应该在哪里打破项链来收集到最大多数的数目的子。
    例如,在图片 A 中的项链,可以收集到8个珠子,在珠子 9 和珠子 10 或珠子 24 和珠子 25 之间打断项链。 在一些项
    链中,包括白色的珠子如图片 B 所示。 当收集珠子的时候,一个被遇到的白色珠子可以被当做红色也可以被当做蓝色。表
    现项链的字符串将会包括三符号 r , b 和 w 。 写一个程序来确定从一条被给出的项链最大可以被收集珠子数目。
    程序名称
    beads



    输入格式
    第 1 行:  N, 珠子的数目 
    第 2 行:  一串度为N的字符串, 每个字符是 r , b 或 w。 



    样例输入
    (文件 beads.in)

    29
    wwwbbrwrbrbrrbrbrwrwwrbwrwrrb



    输出格式
    单独的一行包含从被供应的项链可以被收集的珠子数目的最大值。



    样例输出
    (文件 beads.out)

    11

    ========================= 华丽的分割线 =========================
      这个题目我用的思路是标程里面的一个代码, 用a表示前一段的连续长度, b表示当前段的连续长度, w表示在当前出现的w的连续数目.. 对于对于循环的话, 就把字符串f再复制一份到f后面….
      啥~? 没看懂~? 看样子对于程序员来说最好的语言是代码:

    /*
    PROG: beads
    ID: zqy11001
    LANG: C
    */
    #include <stdio.h>
    #define getint(i) scanf(%d\\n, &n)
    
    int n;
    char f[701];
    
    int main(void)
    {
     int i, limit;
     int a = 0, b = 0, w = 0;
     char c = \'0\';
     int m = 0;
     freopen(beads.in, r, stdin);
     freopen(beads.out, w, stdout);
     getint(n);
     limit = 2 * n;
     fgets(f, 351, stdin);
     memcpy(f + n, f, n);
     for(i = 0; i < limit; i++){
     if(f[i] == \'w\'){
     b++;
     w++;
     }else if(f[i] == c){
     b++;
     w = 0;
     }else{
     if(b + a > m){
     m = b + a;
     }
     a = b - w;
     b = w + 1;
     w = 0;
     c = f[i];
     }
     }
     if(a + b > m){
     m = b + a;
     }
     printf(%d\\n, m > n ? n : m);
     return 0;
    }
  • USACO 2.3 Controlling Companies 控制公司 解题报告

    Controlling Companies 
    
    Some companies are partial owners of other companies because they have acquired part of their total shares of stock. For example, Ford owns 12% of Mazda. It is said that a company A controls company B if at least one of the following conditions is satisfied: 
    
    Company A = Company B 
    Company A owns more than 50% of Company B 
    Company A controls K (K >= 1) companies denoted C1, ..., CK with each company Ci owning xi% of company B and x1 + .... + xK > 50%. 
    Given a list of triples (i,j,p) which denote company i owning p% of company j, calculate all the pairs (h,s) in which company h controls company s. There are at most 100 companies. 
    
    Write a program to read the list of triples (i,j,p) where i, j and p are positive integers all in the range (1..100) and find all the pairs (h,s) so that company h controls company s. 
    
    PROGRAM NAME: concom 
    INPUT FORMAT 
    Line 1: n, the number of input triples to follow 
    Line 2..n+1: Three integers per line as a triple (i,j,p) described above. 
    
    SAMPLE INPUT (file concom.in) 
    3 
    1 2 80 
    2 3 80 
    3 1 20 
    
    OUTPUT FORMAT 
    List 0 or more companies that control other companies. Each line contains two integers that denote that the company whose number is the first integer controls the company whose number is the second integer. Order the lines in ascending order of the first integer (and ascending order of the second integer to break ties). Do not print that a company controls itself. 
    SAMPLE OUTPUT (file concom.out) 
    1 2 
    1 3 
    2 3 

    题目
    有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分。例如,福特公司拥有马自达公司12%的股票。据说,如果至少满足了以下三个条件之一,公司A就可以控制公司B了:

    公司A = 公司B。
    公司A拥有大于50%的公司B的股票。
    公司A控制K(K >= 1)个公司,记为C1, …, CK,每个公司Ci拥有xi%的公司B的股票,并且x1+ …. + xK > 50%。
    给你一个表,每行包括三个数(i,j,p);表明公司i享有公司j的p%的股票。计算所有的数对(h,s),表明公司h控制公司s。至多有100个公司。

    写一个程序读入N组数(i,j,p),i,j和p是都在范围(1..100)的正整数,并且找出所有的数对(h,s),使得公司h控制公司s。

    INPUT FORMAT
    第一行: N,表明接下来三对数的数量。{即(i,j,p)的数量}

    第二行到第N+1行: 每行三个整数作为一个三对数(i,j,p),如上文所述。{表示公司 i 拥有公司j p%的股份}

    SAMPLE INPUT (file concom.in)
    3
    1 2 80
    2 3 80
    3 1 20
    OUTPUT FORMAT
    输出零个或更多个的控制其他公司的公司。每行包括两个整数A、B,表示A公司控制了B公司。将输出的数对以升序排列。

    请不要输出控制自己的公司。

    [编辑] SAMPLE OUTPUT (file concom.out)
    1 2
    1 3
    2 3

    ==================== 华丽的分割线 ====================
    这题对我来说好难,, 实在是难弄出来,, 后来看了提示之后才想到用两个矩阵分别存储公司控制的情况, 如: cont[i][j] 但如果为1 的话代表i公司控制了j公司. 还有一个是占有的股权的矩阵, 如: owns[i][j] 代表i公司直接或间接地占有j公司多少股权..
    C语言:

    /*
    LANG: C
    ID: zqy11001
    PROG:concom
    */
    #include <stdio.h>
    #define MAX 101
    #define getint(i) scanf(%d, &i)
    
    int n;
    int owns[MAX][MAX];
    int cont[MAX][MAX];
    
    void addcont(int a, int b)
    {
     int i;
     if(cont[a][b]){
     return;
     }
     cont[a][b] = 1;
     for(i = 1; i < MAX; i++){
     owns[a][i] += owns[b][i];
     }
     for(i = 1; i < MAX; i++){
     if(cont[i][a]){
     addcont(i, b);
     }
     }
     for(i = 1; i < MAX; i++){
     if(owns[a][i] > 50){
     addcont(a, i);
     }
     }
    }
    
    void addown(int a, int b, int t)
    {
     int i;
    
     for(i = 1; i < MAX; i++){
     if(cont[i][a]){
     owns[i][b] += t;
     }
     }
     for(i = 1; i < MAX; i++){
     if(owns[i][b] > 50){
     addcont(i, b);
     }
     }
    }
    
    int main(void)
    {
     int a, b, t;
     int i, j, k;
     freopen(concom.in, r, stdin);
     freopen(concom.out, w, stdout);
     getint(n);
     for(i = 1; i < MAX; i++){
     cont[i][i] = 1;
     }
     for(i = 1; i <= n; i++){
     getint(a);
     getint(b);
     getint(t);
     addown(a, b, t);
     }
     for(i = 1; i < MAX; i++){
     for(j = 1; j < MAX; j++){
     if(cont[i][j] && i != j){
     printf(%d %d\\n, i, j);
     }
     }
     }
    // getch();
     return 0;
    }
  • USACO 2.4 The Tamworth Two 两只塔姆沃斯牛 解题报告

    The Tamworth Two 
    BIO \'98 - Richard Forster 
    A pair of cows is loose somewhere in the forest. Farmer John is lending his expertise to their capture. Your task is to model their behavior. 
    
    The chase takes place on a 10 by 10 planar grid. Squares can be empty or they can contain: 
    
    an obstacle, 
    the cows (who always travel together), or 
    Farmer John. 
    The cows and Farmer John can occupy the same square (when they `meet\') but neither the cows nor Farmer John can share a square with an obstacle. Each square is 
    represented 
    as follows: 
    
    . Empty square 
    * Obstacle 
    C Cows 
    F Farmer 
    Here is a sample grid: 
    *...*..... 
    ......*... 
    ...*...*.. 
    .......... 
    ...*.F.... 
    *.....*... 
    ...*...... 
    ..C......* 
    ...*.*.... 
    .*.*...... 
    
    The cows wander around the grid in a fixed way. Each minute, they either move forward or rotate. Normally, they move one square in the direction they are facing. If there is an obstacle in the way or they would leave the board by walking `forward\', then they spend the entire minute rotating 90 degrees clockwise. 
    
    Farmer John, wise in the ways of cows, moves in exactly the same way. 
    
    The farmer and the cows can be considered to move simultaneously during each minute. If the farmer and the cows pass each other while moving, they are not considered to have met. The chase ends when Farmer John and the cows occupy the same square at the end of a minute. 
    
    Read a ten-line grid that represents the initial state of the cows, Farmer John, and obstacles. Each of the ten lines contains exactly ten characters using the coding above. There is guaranteed to be only one farmer and one pair of cows. The cows and Farmer John will not initially be on the same square. 
    
    Calculate the number of minutes until the cows and Farmer John meet. Assume both the cows and farmer begin the simulation facing in the `north\' direction. Print 0 if they will never meet. 
    
    PROGRAM NAME: ttwo 
    INPUT FORMAT 
    Lines 1-10: Ten lines of ten characters each, as explained above 
    
    SAMPLE INPUT (file ttwo.in) 
    *...*..... 
    ......*... 
    ...*...*.. 
    .......... 
    ...*.F.... 
    *.....*... 
    ...*...... 
    ..C......* 
    ...*.*.... 
    .*.*...... 
    
    OUTPUT FORMAT 
    A single line with the integer number of minutes until Farmer John and the cows meet. Print 0 if they will never meet. 
    SAMPLE OUTPUT (file ttwo.out) 
    49 
    

    题目描述
    两只牛逃跑到了森林里。农夫John开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和John)。

    追击在10×10的平面网格内进行。一个格子可以是:

    一个障碍物, 两头牛(它们总在一起), 或者 农民John. 两头牛和农民John可以在同一个格子内(当他们相遇时),但是他们都不能进入有障碍的格子。

    一个格子可以是:

    . 空地

    • 障碍物
      C 两头牛
      F 农民John
      这里有一个地图的例子:

      *...*..... 
      ......*... 
      ...*...*.. 
      .......... 
      ...*.F.... 
      *.....*... 
      ...*...... 
      ..C......* 
      ...*.*.... 
      .*.*...... 

      牛在地图里以固定的方式游荡。每分钟,它们可以向前移动或是转弯。如果前方无障碍且不会离开地图,它们会按照原来的方向前进一步。否则它们会用这一分钟顺时针转90度。

    农民John深知牛的移动方法,他也这么移动。

    每次(每分钟)农民John和两头牛的移动是同时的。如果他们在移动的时候穿过对方,但是没有在同一格相遇,我们不认为他们相遇了。当他们在某分钟末在某格子相遇,那么追捕结束。

    读入十行表示农夫John,两头牛和所有障碍的位置的地图。每行都只包含10个字符,表示的含义和上面所说的相同,你可以确定地图中只有一个\’F\’和一个\’C\’.\’F\’和\’C\’一开始不会处于同一个格子中。

    计算农夫John需要多少分钟来抓住他的牛,假设牛和农夫John一开始的行动方向都是正北(即上)。如果John和牛永远不会相遇,输出0。

    PROGRAM NAME: ttwo

    INPUT FORMAT
    第1-10行:

    每行10个字符,表示如上文描述的地图。

    SAMPLE INPUT (file ttwo.in)

    *...*..... 
    ......*... 
    ...*...*.. 
    .......... 
    ...*.F.... 
    *.....*... 
    ...*...... 
    ..C......* 
    ...*.*.... 
    .*.*...... 

    OUTPUT FORMAT
    输出一个数字,表示John需要多少时间才能抓住牛们。如果John无法抓住牛,则输出0。

    SAMPLE OUTPUT (file ttwo.out)
    49

    ======================== 华丽的分割线========================
    这题的话, 应该属于模拟吧(专业术语不太清楚.), 反正就是不停的移动, 只是唯一的一点就是要考虑模拟的上限, 一共有100个方格, 4种方向, 所以单个(牛或者人)一共有400种情况, 那么一共就有160000种情况.

    C语言:

    /*
    LANG: C
    ID: zqy11001
    PROG: ttwo
    */
    #include <stdio.h>
    #define changemap(a, c) if(map[i][j] == c){\\
     a[0] = i;\\
     a[1] = j;\\
     map[i][j] = \'.\';\\
    }
    
    char way1[4] = {-1, 0, 1, 0};
    char way2[4] = {0, 1, 0, -1};
    char map[11][11];
    char f[4], c[4];
    
    void move(char *n)
    {
     int i, j;
     i = n[0] + way1[n[2]];
     j = n[1] + way2[n[2]];
     if(i > 10 || i < 1 || j > 10 || j < 1 || map[i][j] == \'*\'){
     n[2] = (n[2] + 1) % 4;
     }else{
     n[0] = i;
     n[1] = j;
     }
    }
    
    int main(void)
    {
     int i, j;
     freopen(ttwo.in, r, stdin);
     freopen(ttwo.out, w, stdout);
     for(i = 1; i <= 10; i++){
     for(j = 1; j <= 10; j++){
     scanf(%c, &map[i][j]);
     changemap(f, \'F\');
     changemap(c, \'C\');
     }
     getchar();
     }
     for(i = 0; i < 160000 && (f[0] != c[0] || f[1] != c[1]); i++){
     move(f);
     move(c);
     }
     printf(%d\\n, i%160000);
     return 0;
    }
  • USACO 2.4 Cow Tours 牛的旅行 解题报告

    Cow Tours 
    Farmer John has a number of pastures on his farm. Cow paths connect some pastures with certain other pastures, forming a field. But, at the present time, you can find at least two pastures that cannot be connected by any sequence of cow paths, thus partitioning Farmer John\'s farm into multiple fields. 
    Farmer John would like add a single a cow path between one pair of pastures using the constraints below. 
    A field\'s `diameter\' is defined to be the largest distance of all the shortest walks between any pair of pastures in the field. Consider the field below with five pastures, located at the points shown, and cow paths marked by lines: 
     15,15 20,15 
     D E 
     *-------* 
     | _/| 
     | _/ | 
     | _/ | 
     |/ | 
     *--------*-------* 
     A B C 
     10,10 15,10 20,10 
    The `diameter\' of this field is approximately 12.07106, since the longest of the set of shortest paths between pairs of pastures is the path from A to E (which includes the point set {A,B,E}). No other pair of pastures in this field is farther apart when connected by an optimal sequence of cow paths. 
    Suppose another field on the same plane is connected by cow paths as follows: 
     *F 30,15 
     / 
     _/ 
     _/ 
     / 
     *------ 
     G H 
     25,10 30,10 
    In the scenario of just two fields on his farm, Farmer John would add a cow path between a point in each of these two fields (namely point sets {A,B,C,D,E} and {F,G,H}) so that the joined set of pastures {A,B,C,D,E,F,G,H} has the smallest possible diameter. 
    Note that cow paths do not connect just because they cross each other; they only connect at listed points. 
    The input contains the pastures, their locations, and a symmetric adjacency matrix that tells whether pastures are connected by cow paths. Pastures are not considered to be connected to themselves. Here\'s one annotated adjacency list for the pasture {A,B,C,D,E,F,G,H} as shown above: 
     A B C D E F G H 
     A 0 1 0 0 0 0 0 0 
     B 1 0 1 1 1 0 0 0 
     C 0 1 0 0 1 0 0 0 
     D 0 1 0 0 1 0 0 0 
     E 0 1 1 1 0 0 0 0 
     F 0 0 0 0 0 0 1 0 
     G 0 0 0 0 0 1 0 1 
     H 0 0 0 0 0 0 1 0 
    Other equivalent adjacency lists might permute the rows and columns by using some order other than alphabetical to show the point connections. The input data contains no names for the points. 
    The input will contain at least two pastures that are not connected by any sequence of cow paths. 
    Find a way to connect exactly two pastures in the input with a cow path so that the new combined field has the smallest possible diameter of any possible pair of connected pastures. Output that smallest possible diameter. 
    PROGRAM NAME: cowtour 
    INPUT FORMAT 
    Line 1: An integer, N (1 <= N <= 150), the number of pastures 
    Line 2-N+1: Two integers, X and Y (0 <= X ,Y<= 100000), that denote that X,Y grid location of the pastures; all input pastures are unique. 
    Line N+2-2*N+1: lines, each containing N digits (0 or 1) that represent the adjacency matrix as described above, where the rows\' and columns\' indices are in order of the points just listed. 
    SAMPLE INPUT (file cowtour.in) 
    8 
    10 10 
    15 10 
    20 10 
    15 15 
    20 15 
    30 15 
    25 10 
    30 10 
    01000000 
    10111000 
    01001000 
    01001000 
    01110000 
    00000010 
    00000101 
    00000010 
    OUTPUT FORMAT 
    The output consists of a single line with the diameter of the newly joined pastures. Print the answer to exactly six decimal places. Do not perform any special rounding on your output. 
    SAMPLE OUTPUT (file cowtour.out) 
    22.071068 

    描述
    农民 John的农场里有很多牧区。有的路径连接一些特定的牧区。一片所有连通的牧区称为一个牧场。但是就目前而言,你能看到至少有两个牧区通过任何路径都不连通。这样,Farmer John就有多个牧场了。
    John想在农场里添加一条路径(注意,恰好一条)。对这条路径有以下限制:
    一个牧场的直径就是牧场中最远的两个牧区的距离(本题中所提到的所有距离指的都是最短的距离)。考虑如下的有5个牧区的牧场,牧区用“*”表示,路径用直线表示。每一个牧区都有自己的坐标:

     (15,15) (20,15) 
     D E 
     *-------* 
     | _/| 
     | _/ | 
     | _/ | 
     |/ | 
     *--------*-------* 
     A B C 
     (10,10) (15,10) (20,10) 

    这个牧场的直径大约是12.07106, 最远的两个牧区是A和E,它们之间的最短路径是A-B-E。
    这里是另一个牧场:

     *F(30,15) 
     / 
     _/ 
     _/ 
     / 
     *------* 
     G H 
     (25,10) (30,10) 

    这两个牧场都在John的农场上。John将会在两个牧场中各选一个牧区,然后用一条路径连起来,使得连通后这个新的更大的牧场有最小的直径。
    注意,如果两条路径中途相交,我们不认为它们是连通的。只有两条路径在同一个牧区相交,我们才认为它们是连通的。
    输入文件包括牧区、它们各自的坐标,还有一个如下的对称邻接矩阵:

     A B C D E F G H 
    A 0 1 0 0 0 0 0 0 
    B 1 0 1 1 1 0 0 0 
    C 0 1 0 0 1 0 0 0 
    D 0 1 0 0 1 0 0 0 
    E 0 1 1 1 0 0 0 0 
    F 0 0 0 0 0 0 1 0 
    G 0 0 0 0 0 1 0 1 
    H 0 0 0 0 0 0 1 0 

    输入文件至少包括两个不连通的牧区。
    请编程找出一条连接两个不同牧场的路径,使得连上这条路径后,这个更大的新牧场有最小的直径。
    格式
    PROGRAM NAME: cowtour
    INPUT FORMAT:
    (file cowtour.in)
    第1行: 一个整数N (1 <= N <= 150), 表示牧区数
    第2到N+1行: 每行两个整数X,Y (0 <= X ,Y<= 100000), 表示N个牧区的坐标。注意每个 牧区的坐标都是不一样的。
    第N+2行到第2*N+1行: 每行包括N个数字(0或1) 表示如上文描述的对称邻接矩阵。
    OUTPUT FORMAT:
    (file cowtour.out)
    只有一行,包括一个实数,表示所求直径。数字保留六位小数。
    SAMPLE INPUT
    8
    10 10
    15 10
    20 10
    15 15
    20 15
    30 15
    25 10
    30 10
    01000000
    10111000
    01001000
    01001000
    01110000
    00000010
    00000101
    00000010
    SAMPLE OUTPUT
    22.071068
    ====================== 华丽的分割线 ======================
    实在是不会写, 直接看标程,, 但是标程也好难看懂` 思路是大致是
    point是一个结构体, point[i] 表示第i个牧区的坐标:
    引用
    struct point{
    int x, y;
    }point[MAX];
    用一个数组dis[i][j] 表示从第i个牧区到第j个牧区的最短距离(直接间接的都包括在内.), 然后还有一个数组fie[i]表示第i个牧区所在的牧场编号. diam[i]表示在fie[i]这个牧场里距离i最远的牧区之间的距离是多少.. 也就是说diam[i]表示的是同一个牧场中, 距离i最远的牧区和i之间的距离. fdiam[i] 表示编号为i的牧场的直径.
    代码:
    C语言:

    /*
    LANG: C
    ID: zqy11001
    PROG: cowtour
    */
    #include <stdio.h>
    #define INF (1e5)
    #define MAX (150)
    #define getint(i) scanf(%d, &i)
    
    struct point{
     int x, y;
    }point[MAX];
    double dis[MAX][MAX];
    double diam[MAX];
    double fdiam[MAX];
    int fie[MAX];
    int n;
    
    double getdis(int i, int j)
    {
     struct point *a, *b;
     a = &point[i];
     b = &point[j];
     return sqrt((double)(a->x - b->x)*
     (a->x - b->x) +
     (double)(a->y - b->y)*
     (a->y - b->y));
    }
    
    void mark(int i, int m)
    {
     int j;
     if(fie[i] != 0){
     return ;
     }
     fie[i] = m;
     for(j = 0; j < n; j++){
     if(dis[i][j] < INF){
     mark(j, m);
     }
     }
    }
    
    int main(void)
    {
     int i, j, k;
     int c, now = 1;
     double t, max;
     freopen(cowtour.in, r, stdin);
     freopen(cowtour.out, w, stdout);
     getint(n);
     for(i = 0; i < n; i++){
     getint(point[i].x);
     getint(point[i].y);
     }
    
     for(i = 0; i < n; i++){
     getchar();
     for(j = 0; j < n; j++){
     c = getchar();
     if(i == j){
     dis[i][j] = 0;
     }else if(c == \'0\'){
     dis[i][j] = INF;
     }else{
     dis[i][j] = getdis(i, j);
     }
     }
     }
    
     for(i = 0; i < n; i++){
     if(fie[i] == 0){
     mark(i, now++);
     }
     }
    
     for(k = 0; k < n; k++)
     for(i = 0; i < n; i++)
     for(j = 0; j < n; j++){
     if(dis[i][j] > dis[i][k] + dis[k][j]){
     dis[i][j] = dis[i][k] + dis[k][j];
     }
     }
    
     for(i = 0; i < n; i++){
     for(j = 0; j < n; j++){
     if(diam[i] < dis[i][j] && dis[i][j] < INF){
     diam[i] = dis[i][j];
     }
     }
     if(fdiam[fie[i]] < diam[i]){
     fdiam[fie[i]] = diam[i];
     }
     }
    
     max = INF;
     for(i = 0; i < n; i++){
     for(j = 0; j < n; j++){
     if(fie[i] == fie[j]){
     continue;
     }
    
     t = diam[i] + diam[j] + getdis(i, j);
     if(t < fdiam[fie[i]]){
     t = fdiam[fie[i]];
     }
     if(t < fdiam[fie[j]]){
     t = fdiam[fie[j]];
     }
    
     if(t < max){
     max = t;
     }
     }
     }
     printf(%.6lf\\n, max);
     return 0;
    }