zoukankan      html  css  js  c++  java
  • 球——数学分析,模型构建

    我们假设, 一次可以击打任意多相邻连续的红球,也可以只击打一个球。 并且红球既不会落袋,也不会相

    互发生碰撞,而只是停留在原处。每次击打时候,要想“K到红球”,至少要击打一个红球,如果想一次击打

    多个红球,那么击打 的红球必须是依次连续排列的。 如果一次“K到红球”所有红球的标号之和的平均数大于

    母球的标号 (M),就获得了一 个“连击”。

    现在请你帮帮 hs_black 计算总共能有多少种“连击”方案。注意:如果当前有标号为 (1,2,3) 的三种红球,母球标号为 (0),有如下 (6) 种获得“连击”方 案:((1),(2),(3),(1,2),(2,3),(1,2,3))

    输入格式

    输入共有两行,第一行是(N)(M) ((N⩽100000,M⩽10000)) ,NN 表示台面 上一共有 (N) 个红球,(M) 表示

    母球的标 号。 第二行是 (N) 个正整数,依次表示台面上 (N) 个红球的标号,所有标号均不超过 (10000)

    输出格式

    输出只有一个数,为“连击”的方案总数。

    思路

    先说一下暴力,维护一个前缀和,(n^2)的时间复杂度扫一遍就行,

    说正解,学会手玩式子还是挺重要的

    我们要求的就是满足(dfrac{sumleft[ j ight] -sumleft[ i ight] }{j-i} >m)的区间的个数,这里规定(j>i)

    我们变形一下便会得到

    (sumleft[ j ight] -sumleft[ i ight] >mj-mi(j>i))

    (sumleft[ j ight] -mj >sumleft[ i ight] -mi(j>i))

    不妨把(sum[j]-mj)(sum[i]-mi)分别看成单独的两项,即(v[j],v[i])

    问题就简化成了(v[j]>v[i](j>i))

    看到这个我们还是没法用我们已知的算法进行求解,我们看到这个形式不难会想到逆序对

    只要我们再取一次反,不就变成了(v[j]<v[i](j>i)),也就是求逆序对的问题吗

    归并求或者树状数组进行求解都是可以的

    但是这个注意有个小细节,就是如果单独的一个数是大于(m)的,那么它也是满足条件的,

    为了不漏掉这种情况,我们在数的最开始加一个值为0的数

    那会不会对其他情况产生影响呢,答案是不会的,因为我们的(v[])早已经处理好了

    代码

    就是归并排序求逆序对的写法

    #include<bits/stdc++.h>
    using namespace std;
    const int N=200000;
    int sum[N];
    int n,m;
    int a[N];
    template <typename T> inline void read(T &x) {
    	x = 0; char c = getchar();
    	while (!isdigit(c)) c = getchar();
    	while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
    }
    long long res;
    int q[N],tmp[N];
    long long merge_sort(int q[],int l,int r)
    {
        if(l>=r)return 0;
        int mid=(l+r)/2;
        res=merge_sort(q,l,mid)+merge_sort(q,mid+1,r);
        int k=0;
        int i=l;
        int j=mid+1;
        while(i<=mid&&j<=r)
        {
            if(q[i]<=q[j]) tmp[k++]=q[i++];
            else {
                res+=(mid-i+1);
                tmp[k++]=q[j++];
            }
        }
        while(i<=mid)tmp[k++]=q[i++];
        while(j<=r) tmp[k++]=q[j++];
        for(int i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
        return res;
    }
    int main()
    {
    	read(n);
    	read(m);
    	for(int i=1;i<=n;i++)
    	{
    		int x;
    		read(x);
    		sum[i]=sum[i-1]+x;
    	}
    	for(int i=1;i<=n;i++)
    	{
    		sum[i]=sum[i]-i*m;
    		sum[i]=-sum[i];
    	}
        //产生新的sum数组 产生方式就是sum[i]=-(sum[i]-mi)
    	merge_sort(sum,0,n);
    	cout<<res<<endl;
    	return 0;
    }
    
  • 相关阅读:
    VMware中安装Ubuntu后,安装VMwareTools提示“Not enough free space to extract VMwareTools-10.3.10-13959562.tar.gz”的解决办法
    XShell下便捷上载/下载文件到虚拟机
    无法获取 vmci 驱动程序版本: 句柄无效。 驱动程序 vmci.sys 版本不正确。请尝试重新安装 VMware Workstation。 打开模块DevicePowerOn电源失败。
    VMware Workstation pro无法在Windows上运行,检查可在Windows上运行的此应用的更新版本
    mybatisplus运行时修改@TableName注解的schema值
    easyexcel不创建对象导出图片
    鸿蒙(HarmonyOS)开发笔记四:项目结构
    鸿蒙(HarmonyOS)开发笔记三:核心概念
    鸿蒙(HarmonyOS)开发笔记二:使用DevEco Studio创建一个项目
    鸿蒙(HarmonyOS)开发笔记一:系统简介
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/13966458.html
Copyright © 2011-2022 走看看