第二章讨论报告

USACO第一章节讨论报告

 

                     

 

 

                            学校:烟台大学

                            主持:姜庆宇

                            日期:2013年8月15日星期四

                     

        

 

 

 

 

 

 

 

 

 

 

 


第一题 Mixing Milk. 2

第二题BarnRepair2

第三题CalfFlac. 3

第四题PrimeCryptarithm.. 3

第五题PackingRectangles IOI 95. 4

第六题TheClocks5

第七道ArithmeticProgressions6

第八道Mother'sMilk. 6

第九道NumberTriangles7

第十道PrimePalindromes8

第十一道SuperprimeRib. 9

第十二道CheckerChallenge. 9

讨论总结:... 10

(usaco账号: ytjiang1 密码: jiang123)

Section 1.1 1.2 大家认为比较简单,在此没做讨论,直接从section 1.3开始讨论。

第一题 MixingMilk

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=milk

此题比较简单 测试数据有
100 5
5 20
9 40
3 10
8 80
6 30
输出
630

拿到所需的牛奶所要的最小费用。

此题采用贪心算法即可,先根据每单位所需的费用排序,然后计算最小费用即可。

第二题Barn Repair

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=barn1

测试数据有:

4 50 18
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43
输出:
25

此题也比较简单:即先进行排序。根据给的最少使用木板数,找出前n个两个牛栏间的最大距离。也属于贪心范畴。

第三题Calf Flac

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=calfflac

测试数据:

Confucius say:Madam, I'm Adam.

输出

11 Madam, I'm Adam

此题寻找最大回文子串。

此题先讨论了,如何将整篇文字输入。有人用getchar输入。不过最好采用while(getline(fin, str)) s += str;

将整篇文章作为一个字符串处理。然后再将是字母的单独取出来,然后变换成相同的大写,然后求出最大回文子串,然后记录此回文子串是字符串的第N个字母开始,第M个字母结束。

然后输出时查找未处理的字符串,再从第N个字母开始输出,一直到M个字母结束。

 

第四题Prime Cryptarithm

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=crypt1

测试数据:

5
2 3 4 6 8
输出:1
        2 2 2
      x   2 2
    ---------
        4 4 4
      4 4 4
    ---------
     4 8 8 4
即从给的数中取数,满足上式则为牛式。输出表示牛式的总数。
此题有两种做法,但讨论结果是两种的效率差不多。
一种是采用一个五重循环。依次判断每个数是否是牛式。
另外一种是:采用两重循环,即取相乘的两个数,从给定的数中。然后判断后面的结果是否是牛式。因为测试数据很小,一般不会超时,所以此题难度也很低。

第五题PackingRectangles
IOI 95

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=packrec

测试数据:

1 2
2 3
3 4
4 5
输出:
40
4 10
5 8
此题需要分多种情况讨论:
第四种跟第五种的讨论情况是一样的,故分为一种,第六种需要分为两种情况讨论。
另外讨论得,每种情况还需要变换矩形的长和宽,故每种情况还需要变换每个小矩形的位置跟长宽。故需要8重循环。
或者变换长宽时采用1010表示,1代表长宽不兑换,0表示长宽兑换。
然后用数组记录每此变换后求的矩形面积。
第六个图形需要讨论左边下面那个矩形高度跟右边两个矩形高度之和的关系。分为两种情况,1:左边下面那个矩形高度 大于右边两个矩形高度之和
2:左边下面那个矩形高度 大于右边下面矩形高度,但小于右边两个矩形高度之和
 
最后找出最小的然后输出结果。

第六题The Clocks

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=clocks

 

测试数据:

9 9 12
6 6 6
6 3 6
输出:
4 5 8 9

此题讨论比较笨的方法就是:

for(a1 = 0; a1<4; a1++)

       for(a2 = 0; a2<4; a2++)

       for(a3 = 0; a3<4; a3++)

       for(a4 = 0; a4<4; a4++)

       for(a5 = 0; a5<4; a5++)

       for(a6 = 0; a6<4; a6++)

       for(a7 = 0; a7<4; a7++)

       for(a8 = 0; a8<4; a8++)

       for(a9 = 0; a9<4; a9++)

    {

       for(i = 0; i<9; i++)

       {

           tem[i] = a1 *sove[0][i] + a2 *sove[1][i] + a3 *sove[2][i] +

            a4 *sove[3][i] + a5 *sove[4][i] + a6 *sove[5][i] +

            a7 *sove[6][i] + a8 *sove[7][i] + a9 *sove[8][i];

       }

       for(i = 0; i<9; i++)

       {

           if(tem[i] % 4 != ans[i])

                break;

       }

采用一个九重循环。依次找出每个时钟需要几个1,2,3,。。。

然后按照从小到大顺序输出.

因为方案数据可能很长,可达十几位。因此不能从1开始依次+1 向后查找可能的方案,一定会超时。

第七道Arithmetic Progressions

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=ariprog

测试数据:

5 7

输出:

1 4 37 4 2 8 29 8 112 5 12 13 12 17 12 5 20 2 24

 

此题采用空间代替时间, 来判断一个数是否在 p^2+q^2的数的集合

开一个很大的全局数组,形成集合时即:a[1000] = 1;即表示1000在这个集合里;

然后讨论认为循环可以剪枝,但没有这个必要,不剪也不会超时。

两重循环即可求得答案。

 

 

第八道Mother's Milk

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=milk3

测试数据:

2 5 10
输出:
5 6 7 8 9 10
 
采用深搜的做法。

DFS(int A,int B,int C)  //A.B.C 表示当前桶里所剩牛奶

{

    if (found[A][B][C]) return;  //表示已经搜索过 了

    found[A][B][C]=true;

    if (A==0)

    {

       if (!isIn(C))

       {

          ans[p++]=C;

       }

    }

    if (A <= cb-B)

       DFS(0,B+A,C);            //A->B

    else

       DFS( A-(cb-B),cb,C);

    if (A<=cc-C)

       DFS(0,B,C+A);            //A->C

    else

       DFS(A-(cc-C),B,cc);

    if (B<=ca-A)

       DFS(A+B,0,C);            //B->A

    else

       DFS(ca,B-(ca-A),C);

    if (B<=cc-C)

       DFS(A,0,C+B);            //B->C

    else

       DFS(A,B-(cc-C),cc);

    if (C<=ca-A)

       DFS(A+C,B,0);            //C->A

    else

       DFS(ca,B,C-(ca-A));

    if (C<=cb-B)

       DFS(A,B+C,0);            //C->B

    else

       DFS(A,cb,C-(cb-B));

    return;

即当a = 0; 输出c桶的牛奶量即可。

第九道Number Triangles

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=numtri

测试数据

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出:
30

本题主要题意是输入一个三角形,从上至下选择一条路径使得最后求得的和最大。

这是一道很典型的动态规划。其关键代码为:f[i][j] = max(f[i-1][j],f[i-1][j-1]) + map[i][j];

F[i][j] 记录每走一步的最有结果。for(i = 1; i<= num; i++)

    {

       if(mm < f[num][i])

           mm = f[num][i];

}

最后在最后一行求得最大值即为结果。

 

第十道Prime Palindromes

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=pprime

测试数据有

5 500
输出:
5
7
11
101
131
151
181
191
313
353
373
383
本题题意为:输入两个数a和b,在这两个数中间输出所有的回文质数。
思路:先利用循环制造出所有的回文数,存在hui[m]数组里,然后每个判断是否是指数,如果是质数则直接输出,即可。
回文质数除了11其他全为1,3,5,7位数。
for(i = 1; i<=9; i++)
        for(j = 0; j<= 9; j++)
     {
         hui[m++] = i*100 + j* 10 + i ;  //此为3位数的所有回文数。
     }
   while(hui[m] <st) m++;
       while(hui[m]<= en)
       {
           if(IsPrime(hui[m]))
              fout<<hui[m]<<endl;
            m++;
       }
讨论得如果从a到b遍历求回文质数,就算优化也会超时,另外本题的答案最大为9989899 故当b大于这个数时,可直接令b= 9989899.

 

 

第十一道Superprime Rib

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=sprime

测试数据:

4
输出:
2333
2339
2393
2399
2939
3119
3137
3733
3739
3793
3797
5939
7193
7331
7333
7393
此题题意为:输入4则查找所有四位数。例如7331. 7331是质数,733是质数,73是质数,7还是质数。则输出,成为超级质数。
即从最高位开始判断是否是质数,如果不是则加一,如果是,则判断最高位跟次高位的数是否是质数,以此类推。整个数遍历完之后如果是质数则输出。然后 += 2;循环条件为while(st <= en) 4位的话,st = 1001; en = 9999;

 

第十二道Checker Challenge

http://cerberus.delos.com:791/usacoprob2?a=1LjUKRAj7Jg&S=checker

测试数据:

6
输出:
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
此题题意为:此题为n皇后问题。输入为给你一个n*n的棋盘,输出为每一行的列数。一行为一个解决方案,只输出前三个,最后一行输出共有多少种方案。
思路:采用递归的思想。
代码如下.
void que(int i)
{
    int j;
    for(j = 1; j<=num; j++)
    {
        if(column[j] && upl[i-j+ num] && upr[i+j])   //每列,斜着是否满足条件,用这个数组记录很方便,也很快。
        {
            queen[i] = j;column[j] = 0;
            upl[i-j+num] = 0; upr[i+j] = 0;
            if(i<num)
                que(i+1);
            else
            {
                fout<<j<<">"<<i<<endl;  //已经形成一种方案。
                 prt1();  //记数,并输出前三回调用。
            }
            column[j] = upl[i-j+num] = upr[i+j] = 1;
        }
    }
}

讨论总结

利用两个晚上的时间,结束了本次的讨论,此次讨论只要是交流算法,事前由主持人将题目分给组员,每个人讲一到两题。一个人讲后,其他人再补充,如果有更好的算法,提出来大家一起讨论,曾一度两个人对算法效率讨论的很激烈。这样每个人都没有拘束,大胆的提出自己的想法,这里只是记录了一部分的算法,讨论结束后,每个人对题目的理解也加深了很多。讲题人对题目更加了解。此次讨论获得很大的成功。

 


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值