zoukankan      html  css  js  c++  java
  • 2017 09 17 测验解题报告

    预计分数 100+100+20 >=220

    实际分数 100+50+20 =170

    T1 :100

    巧克力棒(chocolate)
    Time Limit:1000ms Memory Limit:64MB
    题目描述
    LYK 找到了一根巧克力棒,但是这根巧克力棒太长了,LYK 无法一口吞进去。
    具体地,这根巧克力棒长为 n,它想将这根巧克力棒折成 n 段长为 1 的巧克力棒,然后
    慢慢享用。
    它打算每次将一根长为 k 的巧克力棒折成两段长为 a 和 b 的巧克力棒,此时若 a=b,则
    LYK 觉得它完成了一件非常困难的事,并会得到 1 点成就感。
    LYK 想知道一根长度为 n 的巧克力棒能使它得到最多几点成就感。
    输入格式(chocolate.in)
    第一行一个数 n。
    输出格式(chocolate.out)
    一个数表示答案。
    输入样例
    7
    输出样例
    4
    数据范围
    对于 20%的数据 n<=5。
    对于 50%的数据 n<=20。
    对于 80%的数据 n<=2000。
    对于 100%的数据 n<=1000000000。
    样例解释
    将 7 掰成 3+4, 将 3 掰成 1+2, 将 4 掰成 2+2 获得 1 点成就感, 将剩下的所有 2 掰成 1+1
    获得 3 点成就感。总共 4 点成就感。

    把一段长度为n的(n为2的幂次方)巧克力二分可以切n-1次,每次用二的幂次方数对区间进行切割,

    递归到长度为1或0(此时无法再切)统计长度

    #include<cstdio>
    int n;
    int dfs(int sum)
    {
        if(sum==1||sum==0)return 0;
        int cnt=1;
        while(cnt*2<=sum) cnt*=2;
        return cnt-1+dfs(sum-cnt);
    }
    int main(){    
        freopen("chocolate.in","r",stdin);
        freopen("chocolate.out","w",stdout);
        scanf("%d",&n);
        printf("%d
    ",dfs(n));
        return 0;
    }

    T2 :50

    错因:队列数组开小应为1000*1000,实为1000

    LYK 快跑!(run)
    Time Limit:5000ms Memory Limit:64MB
    题目描述
    LYK 陷进了一个迷宫! 这个迷宫是网格图形状的。 LYK 一开始在(1,1)位置, 出口在(n,m)。
    而且这个迷宫里有很多怪兽,若第 a 行第 b 列有一个怪兽,且此时 LYK 处于第 c 行 d 列,此
    时这个怪兽对它的威胁程度为|a-c|+|b-d|。
    LYK 想找到一条路径,使得它能从(1,1)到达(n,m),且在途中对它威胁程度最小的怪兽的
    威胁程度尽可能大。
    当然若起点或者终点处有怪兽时,无论路径长什么样,威胁程度最小的怪兽始终=0。
    输入格式(run.in)
    第一行两个数 n,m。
    接下来 n 行,每行 m 个数,如果该数为 0,则表示该位置没有怪兽,否则存在怪兽。
    数据保证至少存在一个怪兽。
    输入格式(run.out)
    一个数表示答案。
    输入样例
    3 4
    0 1 1 0
    0 0 0 0
    1 1 1 0
    输出样例
    1
    数据范围
    对于 20%的数据 n=1。
    对于 40%的数据 n<=2。
    对于 60%的数据 n,m<=10。
    对于 80%的数据 n,m<=100。
    对于 90%的数据 n,m<=1000。
    对于另外 10%的数据 n,m<=1000 且怪兽数量<=100。

    bfs处理出每个点与距离最近怪兽的距离,二分答案,二分路径上的最小值用bfs进行检验

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int maxn = 1003; 
    int que[maxn*maxn][2],cnt=0;
    int map[maxn][maxn];
    int dis[maxn][maxn];
    struct Node{
        int x,y;
    }node[400];
    int fs[5]={1,0,-1,0,1};
    int n,m;
    void bfs() {
        int head=0,tail=cnt;
        while(head<=tail) {
            int x=que[++head][0],y=que[head][1];
            for(int i=0;i<4;i++) {
                int xx=x+fs[i],xy=y+fs[i+1];
                if(xx>=1&&xx<=n&&xy>=1&&xy<=m&&!map[xx][xy]&&!dis[xx][xy]) {
                    dis[xx][xy]=dis[x][y]+1;
                    que[++tail][0]=xx,que[tail][1]=xy;
                }
            }
        }
    }
    bool vis[maxn][maxn];
    bool judge(int ans) {
        int head=0,tail=1;
        memset(que,0,sizeof que);
        memset(vis,0,sizeof vis);
        que[1][0]=1,que[1][1]=1,vis[1][1]=1;
        while(head<tail) {
            int x=que[++head][0],y=que[head][1];
            for(int i=0;i<4;i++) {
                int xx=x+fs[i],xy=y+fs[i+1];
                if(xx>=1&&xx<=n&&xy>=1&&xy<=m&&dis[xx][xy]>=ans&&!map[xx][xy]&&!vis[xx][xy]) {
                    if(xx==n&&xy==m)return true;
                    que[++tail][0]=xx,que[tail][1]=xy;vis[xx][xy]=1;
                }
            }
        }
        return false;
    }
    int main() {
        freopen("run.in","r",stdin);
        freopen("run.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                scanf("%d",&map[i][j]);
                if(map[i][j]==1)que[++cnt][0]=i,que[cnt][1]=j;
                }
        if(map[1][1]||map[n][m]){
            puts("0");return 0;
        }
        bfs();
        int l=0,r=1000006;
        int ans;
        while(l<=r) {
            int mid=(l+r)/2;
            if(judge(mid)) {
                l=mid+1;
                ans=mid;
            }
            else r=mid-1;
        }
        printf("%d
    ",ans);
        return 0;
    }

    T3 : 20 

    错因 不会....tarjan+乱搞

    仙人掌(cactus)
    Time Limit:1000ms Memory Limit:64MB
    题目描述
    LYK 在冲刺清华集训(THUSC) !于是它开始研究仙人掌,它想来和你一起分享它最近
    研究的结果。
    如果在一个无向连通图中任意一条边至多属于一个简单环 (简单环的定义为每个点至多
    经过一次) ,且不存在自环,我们称这个图为仙人掌。
    LYK 觉得仙人掌还是太简单了,于是它定义了属于自己的仙人掌。
    定义一张图为美妙的仙人掌, 当且仅当这张图是一个仙人掌且对于任意两个不同的点 i,j,
    存在一条从 i 出发到 j 的路径,且经过的点的个数为|j-i|+1 个。
    给定一张 n 个点 m 条边且没有自环的图,LYK 想知道美妙的仙人掌最多有多少条边。
    数据保证整张图至少存在一个美妙的仙人掌。
    输入格式(cactus.in)
    第一行两个数 n,m 表示这张图的点数和边数。
    接下来 m 行,每行两个数 u,v 表示存在一条连接 u,v 的无向边。
    输出格式(cactus.out)
    一个数表示答案
    输入样例
    4 6
    1 2
    1 3
    1 4
    2 3
    2 4
    3 4
    输出样例
    4
    样例解释
    选择边 1-2,1-3,2-3,3-4,能组成美妙的仙人掌,且不存在其它美妙仙人掌有超过 4 条
    边。
    数据范围
    对于 20%的数据 n<=3。
    对于 40%的数据 n<=5。
    对于 60%的数据 n<=8。
    对于 80%的数据 n<=1000。
    对于 100%的数据 n<=100000 且 m<=min(200000,n*(n-1)/2)。

    对于i和i+1点要过2个点,即只能为这两个点之间直接有一条边,那么这n-1条连接i和i+1的边一定选,选完这些边之后正好满足

    要在保证仙人掌的前提下多选边

    保证边没有交集因为现在已经选了i到i+1的边其他的边会和现在已经选的边形成环,否则,两个边有交集,不满足仙人掌的性质,所以问题转化成了线段覆盖

    #include<cstdio>
    #include<algorithm> 
    using namespace std;
    const int maxn =200010;
    int n,m,cnt,ans;
    struct Edge{
        int x,y; 
        bool operator < (const Edge &x)const{
            return y<x.y;
        }
    }edge[maxn*2];
    int main()
    {
        freopen("cactus.in","r",stdin);
        freopen("cactus.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int a,b,i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            if(a>b)swap(a,b);
            if(a!=b-1)edge[++cnt].x=a,edge[cnt].y=b;
        }
        sort(edge+1,edge+cnt+1);
        int tail=-1;
        for(int i=1;i<=cnt;i++) {
            if(edge[i].x>=tail) {
                tail=edge[i].y;
                ans++;
            }
        }
        printf("%d
    ",ans+n-1);
        return 0;
    }
  • 相关阅读:
    15-01-18 C# 面向对象 13
    15-01-15 C# 面向对象 12
    15-01-12 C# 面向对象 11
    15-01-11 C# 面向对象 10
    15-01-10 C# 面向对象 09
    了解 Azure 中的无服务器计算
    了解 Azure 虚拟机
    什么是 Azure?
    云服务的类型
    云部署模型
  • 原文地址:https://www.cnblogs.com/sssy/p/7537828.html
Copyright © 2011-2022 走看看