关于Algorithm 105的考试总结

来源:互联网 发布:app软件更新不了 编辑:程序博客网 时间:2024/05/22 03:21

  • T1东东的蚂蚱
    • 题目描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 数据范围
    • 代码
      • 算法解释
      • 单题总结
  • T2东东被困沼泽地
    • 题目描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 数据范围
    • 代码
      • 所用算法
      • 单题总结
  • T3东东爸建机房 buildcpp
    • 题目描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 数据范围
    • 代码
      • 所用算法
    • 总结

T1东东的蚂蚱

题目描述

东东爸给东东带回来一只聪明的蚂蚱,据说这个蚂蚱认识英文字母,好神奇的事情哦~~
为了测试这件事情,东东拿来一条长长的纸带,上面有N个格子排成一列,每一个格子中都有一个大写的字母。东东每次把聪明的蚂蚱放在地纸带的最前面聪明的蚂蚱就会一直向前跳,跳到它喜欢的字母的格子中,最后跳出纸带
经过观察,东东发现蚂蚱只喜欢特定的M个大写字母;并且聪明的蚂蚱的弹跳能力极强,每次跳越的距离为[1,X]区间中的某一个正整数。
现给出一条新的纸带,以及蚂蚱喜欢的特定的字母。东东想知道X的最小值为多少?

输入格式

第一行两个正整数N和M
第二行M个大写字母组成的字符串,为聪明的蚂蚱喜欢的那M个字母(M个字母互不相同)。
第三行为N个大写字母的组成的字符串,表示纸带上每个格子中的字母。

输出格式

一行一个正整数,表示最小的X值。

样例输入

9 3
ACU
CQZHANGYU

样例输出

4

数据范围

N<=10000, 1<=M<=26

代码

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;char standard[30],word[10010];int Wordlen,Lovelen;int check(int x){    for(int i=1;i<=Lovelen;i++)        if(word[x]==standard[i])            return 1;    return 0;}int main(){    freopen("jump.in","r",stdin);    freopen("jump.out","w",stdout);    int ans=0;    scanf("%d%d",&Wordlen,&Lovelen);    for(int i=0;i<=Lovelen;i++)        scanf("%c",&standard[i]);    for(int i=0;i<=Wordlen;i++)        scanf("%c",&word[i]);    Wordlen++;    word[Wordlen]=standard[1];    int t=0;    for(int i=1;i<=Wordlen;i++)    {        if(check(i))        {            ans=max(ans,i-t);            t=i;        }    }    printf("%d",ans);    fclose(stdin);    fclose(stdout);    return 0;}

算法解释

模拟,注意边界

单题总结

这道题很水,但最开始没有看到边界的条件,就很可能爆了零。所以,下次做题要认真读题中的每个字再开始写代码。

T2东东被困沼泽地

题目描述

东东和东东爸跑出去野外穿越,结果不想东东被困在了一处沼泽地里。东东爸通过观察这片沼泽地是一个N*M的矩阵A,每一个位置要么是要命的泥沼,要么是坚硬的石头。如果Aij <0表示的泥沼,否则就是石头
初始东东爸在(1,1)位置,并且只能向右和向下走,因为这样才能最快的接近被困在(N,M)位置的东东。每走到一个位置就得到这个位置的值,问如何确定方案,东东爸才能在获得最大的值的情况下救出东东呢?(东东爸强到可以强过泥沼)
规定的行走方案由下面3条组成:
1、每次可以向右走一格。例如:(x,y)->( x,y+1 )
2、每次可以向下走一格。例如:(x,y)->( x+1,y )
3、每次可以向右走到当前列编号的整数倍的编号的格子。例如:(x,y)->( x,y*k ),其中k为合法的正整数。

输入格式

第一行两个正整数N和M。
接下来N行,每行M个整数。用来描述矩阵A。其中位置(1,1)和(N,M)的值为0。

输出格式

一行一个正整数,表示东东爸救出东东的情况下获得的最大值。

样例输入

3 3
0 1 1
1 1 1
1 1 0

样例输出

3

数据范围

2

代码

#include <algorithm>#include <iostream>#include <cstdio>#include <cstring>using namespace std;int map[210][210],f[210][210];int main(){    freopen("trap.in","r",stdin);    freopen("trap.out","w",stdout);    int n,m;    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            scanf("%d",&map[i][j]);    for(int i=0;i<=200;i++)        f[i][0]=-2147483647;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)        {            f[i][j]=max(f[i-1][j],f[i][j-1])+map[i][j];            for(int k=1;k<j;k++)                if(j%k==0)                {                    f[i][j]=max(f[i][j],f[i][k]+map[i][j]);                }        }    printf("%d\n",f[n][m]);    fclose(stdin);    fclose(stdout);    return 0;}

所用算法

DP,注意要初始一下f[i][0]为极小值,为保证f[i][1]的值是从f[i-1][1]传过来的

单题总结

因为没有初始化f数组导致WA了两个点,下次做题时要注意边界!!

T3东东爸建机房 (build.cpp)

题目描述

吉林省的信息学奥林匹克竞赛的成绩越来越好,吸引了非常多的有志学生选择学习信息学竞赛。但是现有机房的电脑明显是不够用了,东东爸就建议再建立一个超级大的机房。但是预算却非常有限,逼的东东爸在能省的地方绝对不会多花一分钱。
现在已知一共N个设备,编号为1到N。设备分两种,交换机或者电脑。上网规则如下:
1、所有的交换机都连了外网。
2、如果某台电脑i直连了交换机那么电脑i就能上网。
3、如果电脑i能上网,电脑j连接了电脑i,那么电脑j也能上网。
但是布线的施工方却是个奸商,虽然最后保证了所有的电脑都能上网了,但是布线时布了非常多的没有用的网线,甚至居然有几台电脑都成了环状拓扑结构了。东东爸火冒三丈,要求施工方撤掉尽可能多的网线,还得保证所有的机器都能上网。
怕施工方耍滑头,你能先帮东东爸算算最多能撤销的网线的长度么?

输入格式

第一行三个正整数N、M和K,表示有N个设备,M条网线,K台交换机。
第二行有K个正整数,表示交换机的编号。
接下来M行三个正整数x,y,z。表示x号设备到y号设备的网线长度为z。

输出格式

一个整数表示最多能撤销的网线的总长度。

样例输入

5 7 2
1 2
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10

样例输出

38

数据范围

保证 N≤1000 ,M<=10000 , 0<=k<=10, 0

代码

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;struct ed{    int dot1;    int dot2;    int len;}path[10010];bool cmp(ed a,ed b){    return a.len<b.len;}int Numdot,Numpath;int fa[1010],ans=0;int find(int x){    if(fa[x]==x)        return x;    return fa[x]=find(fa[x]);}int main(){    freopen("build.in","r",stdin);    freopen("build.out","w",stdout);    for(int i=1;i<=1000;i++)fa[i]=i;    int NumZdot,Fatemp;    scanf("%d%d%d",&Numdot,&Numpath,&NumZdot);    scanf("%d",&Fatemp);    for(int i=1;i<NumZdot;i++)    {        int temp;        scanf("%d",&temp);        fa[temp]=Fatemp;    }    for(int i=1;i<=Numpath;i++)        scanf("%d%d%d",&path[i].dot1,&path[i].dot2,&path[i].len);    sort(path+1,path+1+Numpath,cmp);    for(int i=1;i<=Numpath;i++)    {        int faa,fab;        faa=find(path[i].dot1);        fab=find(path[i].dot2);        if(faa!=fab)        {            fa[faa]=fab;        }else        {            ans+=path[i].len;        }    }    cout<<ans;    fclose(stdin);    fclose(stdout);    return 0;}

所用算法

克鲁斯卡尔最小生成树,处理交换机时可以把交换机间连上长度为0的边(裸题)

总结

认真读题,注意边界。

0 0
原创粉丝点击