zoukankan      html  css  js  c++  java
  • Wannafly挑战赛3

    给你一个长 n 的序列,m 次查询

    每次查询给一个 x,然后:

    从序列的最左端 1 开始,每次随机的选择一个右端点 r,如果两个端点间的区间和不超过 x ,就进行一次分割,然后把左端点变成 r + 1, 否则一直随机下去。

    问这样分割出来的期望段数

    输入描述:

    第一行两个数 n,m
    之后一行 n 个数表示这个序列
    之后m行每行一个数 x,表示求每段的和不大于 x 的情况下切割的期望段数

    输出描述:

    m 行,每行一个保留到小数点后2位的数表示答案
    如果无论如何都没有合法的切割方案,输出"YNOI is good OI!",不含引号

    示例1

    输入

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

    输出

    YNOI is good OI!
    4.25
    3.83
    3.58
    3.58
    3.11

    说明

    对于30%的数据,n , m <= 10
    对于60%的数据,n <= 1000 , m <= 10
    对于80%的数据,n <= 100000 , m <= 100
    对于100%的数据,n <= 100000 , m <= 500 , 0 <= a[i] <= 1000 , x <= 1000000

    看了好久才知道题意。。。
    就是把n个数分段,要求每一段的区间和小于等于x,然后求一下期望段数
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=1e5+88;
    int a[N],sum[N],n,m,x;
    double dp[N],Sum[N];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) {scanf("%d",a+i);sum[i]=a[i]+sum[i-1];}
        while(m--){
        bool ok=1;
        scanf("%d",&x);
        int pos=n;
        for(int i=n;i>=1;--i) {
            if(a[i]>x) {ok=0;break;}
            else {
                while(sum[i-1]+x<sum[pos]) --pos;
                double shu=pos-i+1;
                dp[i]=(Sum[i+1]-Sum[pos+2])/shu+1;
            }
            Sum[i]=Sum[i+1]+dp[i];
        }
        if(!ok) puts("YNOI is good OI!");
        else printf("%.2f
    ",dp[1]);
        }
    }

    题目描述

    给一个数组{a},定义 h(a,b)为在十进制下 a + b 与 a 的位数差,求 ,0的位数为1。
     

    输入描述:

    第一行读入一个正整数 n (1 <= n <= 105)。

    第二行读入 n 个非负整数,第 i 个表示a[i] (0 <= a[i] <= 108)。

    输出描述:

    一行表示答案。
    示例1

    输入

    10
    0 1 2 3 4 5 6 7 8 9

    输出

    20

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1e5+88;
    int sum[N],n,a[N],san[N],b[N];
    long long s[15];
    void add(int p){
        for(;p<=n+55;p+=(p&(-p))) ++sum[p];
    }
    int query(int p){
        int ans=0;
        for(;p;p-=(p&(-p))) ans+=sum[p];
        return ans; 
    }
    int main(){
        long long ans=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i) scanf("%d",a+i),b[i]=a[i];
        sort(b+1,b+n+1);
        b[0]=0;
        s[1]=0,s[2]=10;
        for(int i=3;i<=14;++i) s[i]=s[i-1]*10;
        for(int i=1;i<=n;++i) san[i]=lower_bound(b+1,b+n+1,a[i])-b;
        for(int i=n;i>=1;--i){
            int now=a[i],wei=0,cha;
            if(!now) wei=1;
            while(now){
                now/=10;
                ++wei;
            }
            int ct=wei;
            while(1){
                ++wei;
                cha=s[wei]-a[i];
                int xia=lower_bound(b+1,b+n+1,cha)-b-1;
                if(xia==n) break;
                ans+=query(n+1)-query(xia);
            }
            add(san[i]);
        }
        printf("%lld
    ",ans);
    }
    给定一个 n*m 的矩阵,矩阵元素由X和O构成,请求出其中最大的蝴蝶形状。
    蝴蝶形状的定义如下:
    存在一个中心点(必须为X),并且其往左上(必须为X)、左下(必须为X)、右上(必须为O)、右下(必须为O)四个方向扩展相同的长度,且左上顶点与左下顶点之间全由X填充,右上顶点与右下顶点之间全由O填充。
    我们不在意在蝴蝶形状内部是X还是O。
    例如:
        XAAAO
        XXAOO
        XAXAO
        XXAOO
        XAAAO
    是一个蝴蝶形状(其中A表示X或O)。
        X
    也是。

        XAAO
        XXOO
        XXOO
        XAAO
    不是(不存在中心点)。

    输入描述:

    第一行两个整数n, m表示矩阵的大小 (1 <= n, m <= 500);
    接下来 n 行,每行一个长度为 m 的字符串表示矩阵,矩阵元素保证由X和O构成。

    输出描述:

    一行一个整数表示最大的蝴蝶形状的对角线的长度。

    示例1

    输入

    5 5
    XOOOO
    XXOOO
    XOXOO
    XXOOO
    XOOOO

    输出

    5

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char mp[508][508];
    int n,m;
    bool Ju(int x,int y,int k,int size){
        if(mp[x+k][y+k]=='O'||mp[x+k][y+size-1-k]=='X') return true;
        if(mp[x+size-1-k][y+k]=='O'||mp[x+size-1-k][y+size-1-k]=='X') return true;
        return false;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;++i) scanf("%s",mp[i]);
        int maxx=min(n,m);
        if((maxx&1)^1) --maxx;
        bool ok=0;
        for(int size=maxx;~size;size-=2) if(ok) break; else  for(int i=0;i<=n-size;++i){
            int sj=(size+1)/2;
            for(int j=0;j<=m-size;++j) {
                if(mp[i+sj-1][j+sj-1]!='X') continue;
                bool fl=1;
                for(int k=0;k<sj-1;++k) if(Ju(i,j,k,size)) {fl=0;break;}
                if(!fl) continue;
                for(int k=0;k<size;++k) if(mp[i+k][j]!='X') {fl=0;break; }
                if(!fl) continue;
                for(int k=0;k<size;++k) if(mp[i+k][j+size-1]!='O'&&size!=1) {fl=0;break;}
                if(fl) {ok=1;break;}
            }
            if(ok) {printf("%d
    ",size);break;}
        }
        if(!ok) puts("0");
    }
  • 相关阅读:
    移动端兼容
    三点优化
    面向对象(一)
    BootCDN和npm
    分页逻辑
    多物体运动框架
    兼容样式
    省略
    行内元素在水平和垂直排列的时候会有间距
    [Swift]LeetCode1053.交换一次的先前排列 | Previous Permutation With One Swap
  • 原文地址:https://www.cnblogs.com/mfys/p/7818846.html
Copyright © 2011-2022 走看看