Daemon's tech-blog

If you want a miracle, to be the miracle!

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

USACO Chapter 1

Section 1.1

1.1.1 Your Ride Is Here (ride)

    USACO的第一个程序,主要是熟悉环境的
    注意两点:
    1.扫描字符串,不需要取strlen,只需判断s[i]是否为真即可
    2.return语句只能用于非void类型的函数,只结束子程序
      exit语句通用,而且终结整个程序

1.1.2 Greedy Gift Givers (gift1)

    很简单的模拟
    注意以下几点:
    1.函数间字符串的传递,返回指针的函数
    2.指针操作的便捷性
    3.考虑除数等于0的情况

1.1.3 Friday the Thirteenth (friday)

    日历问题也是个常见的问题
    1.关键是明确从哪一天算起,到哪一天为止,头尾是否没算或多算了!
    2.假设今天是星期n,则days天后为星期(n + days%7) % 7
    3.蔡勒公式
        w = ((c / 4) - (2 * c) + y + (y / 4) + (26 * (m + 1) / 10) + d - 1) % 7
        w:所求星期数;
        c:年份前两位数;
        y:年份后两位数;
        m:月份数;
        d:日数。
        里面所有除法不保留小数。
        如果月份为1月或2月,则看作上年的13或14月。
    本题要注意文件尾要有空行!!!

1.1.4 Broken Necklace (beads)

    本题有三种解法:
    1.标准暴力,对每一点都向前向后搜索,取最大值,O(n)
    2.优化暴力,将串增倍,从头到尾搜索一次即可,记录上次最长段和本次最长段
    3.动态规划思想

    解题过程中要注意
    1.全白的情况 && 超过总长的情况
    2.最后一次的记录

 Section 1.2

1.2.1 Milking Cows (milk2)

      三种方法:
      1.先对开始时间进行排序,再扫描一遍即可,扫描时(cur表示current)
          若milk[i].begin > cur.end则断开
          若milk[i].begin <= cur.end && cur.end < milk[i].end则两个可合并
          若milk[i].begin <= cur.end && cur.end >= milk[i].end则milk[i]可忽略
      2.开一个10^6的标记数组,对n个时间段扫描一次标记,O(mn),会超时
    3.对第一个事件的开始和结束独立看待,开始记1,结束记-1,从开始扫一遍累加,
        从0变到非0则是一段新的有人挤奶的开始,从非0变到0则是一段新的无人挤奶的开始
 
    编码技巧:
    1.规范typedef strct XXX XXX
    2.qsort的调用:
      (1)加文件头stdlib.h
      (2)void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *));
         各参数:待排序数组首地址;待排序元素数量;各元素空间大小;指向函数的指针,确定排序的顺序
      (3)自定义cmp函数
    3.数据初始化
    4.搜索(扫描)之前先给定初始状态,最后别忘了擦屁股

1.2.2 Transformations (transform)

    旋转与翻转,a->b
    1.顺时针旋转90度:  b[i][j] = a[n-j-1][i]
    2.顺时针旋转180度: b[i][j] = a[n-i-1][n-j-1]
    3.左右翻转:           b[i][j] = a[i][n-j-1]
    4.下下翻转:           b[i][j] = a[n-i-1][j]

    编码:
    1.函数不能返回数组,但可以把数组包装在结构体里
    2.二维数组的传递
        调用function(arrayname);
        函数头function(arrytype arrayname[][MAXLEN])
    3.读入二维字符数组可以按行读
        char *gets(char * ptr);
        char *fgets(char *string, int n, FILE *stream);
        参数:*string结果数据的首地址;n-1:一次读入数据块的长度,其默认值为1k,即1024;stream文件指针
    4.按照题目所说的顺序模拟判断

1.2.3 Name That Number (namenum)

    思路1:由数字产生字符串,然后在字典里二分查找,O(3^12*log5000)=O(6.5e6)
    思路2:由字符串转化为数字再判断,可以先判断长度,再比较各位,而由字母转化为数字可以分两段(由于缺Q)除以3,也可建个code表

      编码:
      1.fgets与gets
          char *fgets(char *string, int n, FILE *stream);
          char *gets(char *ptr);
          区别fgets会读取换行符而gets读到换行符会当作'"0'保存

1.2.4 Palindromic Squares (palsquare)

    纯粹的进制转换(如将十进制s转换为b进制)
    for (j = 0; k[j] = code[s%b], s /= b; j++)
        ;

    编码:
    1.多运用指针,代码简练效率高
    2.getc与putc
        int getc(FILE *stream)
        int putc(int ch, FILE *stream);

1.2.5 Dual Palindromes (dualpal)

    从s+1开始枚举每个十进制数,判断是否为dualpal即可

    编码:
    注意计数变量的初始化位置

 Section 1.3

1.3.1 Mixing Milk (milk)

    贪心,主要有两种思路:
    1.按价格对farmer进行排序,然后从前向后取即可
    2.考虑到price范围只有0..1000,可以做个表price[0..1000]存放每个单价上可以提供的奶量,
      然后扫一遍price表

1.3.2 Barn Repair (barn1)

    三种思路:
    1.贪心,先用一块大板将第一个牛到最后一个牛都覆盖,然后不断找最大空隙,从中间隔开,直到达到木板数
        其中要注意两点:1.数据未必有序;2.板数比牛数还大的情况
    2.贪心,先覆盖每一个牛一块木板,然后不断找其中间隔最小的,合并之,直到达到木板数
        同上,也要注意两点
    3.DP,将有牛的牛棚排序后,
        设d[i,j]表示第i个牛修到第j个牛需要使用的木板长度,
        设f[i,j]表示用前i个木板修到第j头牛所用的最短长度.
        方程:f[i,j]=f[i-1,k-1]+d[k,j]  (i<=k<=j)

1.3.3 Calf Flac

1.3.4 Prime Cryptarithm

 Section 1.4

1.4.1 Packing Rectangles

1.4.2 The Clocks

1.4.3 Arithmetic Progressions

1.4.4 Mother's Milk

 Section 1.5

1.5.1 Number Triangles

1.5.2 Prime Palindromes

1.5.3 SuperPrime Rib

1.5.4 Checker Challenge



 

posted on 2009-02-03 21:09  ACing  阅读(330)  评论(0)    收藏  举报