• 10.31 afternoon


    巧克力棒(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 点成就感。

     结论没推出来 Dfs+map 不过还是0ms

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #define maxn 1010
    using namespace std;
    int n,a[maxn],c;
    map<int,int>f;
    int Dfs(int x){
        if(f[x]||x==1|x==0)return f[x];
        int pos=upper_bound(a+1,a+1+a[0],x)-a-1;
        if(a[pos]==x){
            f[x]=x-1;return f[x];
        }
        f[x]=Dfs(a[pos])+Dfs(x-a[pos]);
        return f[x];
    }
    int main()
    {
        freopen("chocolate.in","r",stdin);
        freopen("chocolate.out","w",stdout);
        cin>>n;c=1;
        for(int i=1;i<=35;i++){
            a[++a[0]]=c<<i;
            if((c<<i)>n)break;
        }
        f[2]=1;f[3]=1;
        cout<<Dfs(n);
        return 0;
    }
    View Code

    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

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define pa pair<int,int>
    #define mk make_pair
    #define X first
    #define Y second
    #define maxn 1010
    using namespace std;
    int n,m,k,ans,g[maxn][maxn],s[maxn][maxn],f[maxn][maxn];
    queue<pa>q;
    int xx[4]={0,0,1,-1};
    int yy[4]={1,-1,0,0};
    int init(){
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    bool Judge(int S){
        if(s[1][1]<S)return 0;
        memset(f,0,sizeof(f));
        while(!q.empty())q.pop();
        q.push(mk(1,1));f[1][1]=1;
        while(!q.empty()){
            int x=q.front().X;
            int y=q.front().Y;
            q.pop();
            if(x==n&&y==m)return 1;
            for(int i=0;i<4;i++){
                int nx=x+xx[i];
                int ny=y+yy[i];
                if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&f[nx][ny]==0&&s[nx][ny]>=S){
                    f[nx][ny]=1;q.push(mk(nx,ny));
                }
            }
        }
        return 0;
    }
    int main(){
        freopen("run.in","r",stdin);
        freopen("run.out","w",stdout);
        n=init();m=init();
        memset(s,127/3,sizeof(s));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                g[i][j]=init();
                if(g[i][j]){
                    q.push(mk(i,j));
                    s[i][j]=0;f[i][j]=1;
                }
            }
        if(g[1][1]==1||g[n][m]==1){
            printf("0
    ");return 0;
        }
        while(!q.empty()){
            int x=q.front().X;
            int y=q.front().Y;
            q.pop();
            for(int i=0;i<4;i++){
                int nx=x+xx[i];
                int ny=y+yy[i];
                if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&f[nx][ny]==0){
                    s[nx][ny]=min(s[nx][ny],s[x][y]+1);
                    f[nx][ny]=1;q.push(mk(nx,ny));
                }
            }
        }
        int l=0,r=n*m;
        while(l<=r){
            int mid=l+r>>1;
            if(Judge(mid)){
                l=mid+1;ans=mid;
            }
            else r=mid-1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code


    仙人掌(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)。

    考试的时候骗了40 2333

    正解比较裸

    /*
    飘渺的题意....
    美妙的仙人掌包含了1-n所有的点
    题目中要求任意ij满足条件 那么每个i和i+1一定先连边
    这里的ij是整张图的ij 不是仅仅包括仙人掌的哪一坨
    那1-n就构成了一条链 考虑剩下的边 每连两条 u1u2 v1v2
    看做两端区间 如果重叠的话 就不是仙人掌了
    也就是说 先保证满足条件 (连成一条链)然后选尽量多的边
    就成了线段覆盖
    */
    #include<cstdio>
    #include<algorithm>
    #define maxn 100010
    using namespace std;
    int n,m,cnt;
    struct node{
        int u,v;
        bool operator < (const node &x)const{
            return v<x.v;
        }
    }e[maxn*2];
    int init(){
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    int main()
    {
        freopen("cactus.in","r",stdin);
        freopen("cactus.out","w",stdout);
        n=init();m=init();
        int u,v;
        for(int i=1;i<=m;i++){
            u=init();v=init();
            if(u>v)swap(u,v);
            if(u!=v-1){    
                e[++cnt].u=u;e[cnt].v=v;
            }
        }
        sort(e+1,e+1+cnt);
        int r=0,sum=0;
        for(int i=1;i<=cnt;i++)
            if(e[i].u>=r){
                sum++;r=e[i].v;
            }
        printf("%d
    ",sum+n-1);
        return 0;
    }
    View Code
  • 相关阅读:
    Java for LeetCode 229 Majority Element II
    Java for LeetCode 228 Summary Ranges
    Java for LeetCode 227 Basic Calculator II
    Java for LintCode 颜色分类
    Java for LintCode 链表插入排序
    Java for LintCode 颠倒整数
    Java for LintCode 验证二叉查找树
    Java for LeetCode 226 Invert Binary Tree
    Java for LeetCode 225 Implement Stack using Queues
    Java for LeetCode 224 Basic Calculator
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/6037502.html
Copyright © 2020-2023  润新知