zoukankan      html  css  js  c++  java
  • 洛谷P2381 圆圆舞蹈

    P2381 圆圆舞蹈

    题目描述

    熊大妈的乃修在时针的带领下,围成了一个圆圈舞蹈,由于没有严格的教育,奶牛们之间的间隔不一致。

    奶牛想知道两只最远的奶牛到底隔了多远。奶牛A到B的距离为A顺时针走和逆时针走,到达B的较短路程。告诉你相邻两个奶牛件的距离,请你告诉奶牛两只最远的奶牛到底隔了多远。

    输入输出格式

    输入格式:

    第一行一个整数N,表示有N只奶牛。(2<=N<=100000)

    接下2-N+1行,第i行有一个数,表示第i-1头奶牛顺时针到第i头奶牛的距离。(1<=距离<=maxlingint,距离和<=maxlongint)

    第N+1行的数表示第N头奶牛顺时针到第1头奶牛的距离。

    输出格式:

    一行,表示最大距离。

    输入输出样例

    输入样例#1:
    Crile.in
    5
    1
    2
    3
    4
    5
    
    输出样例#1:
    Crile.out
    7


    Solution 做法1:
    记录前缀和,可知前缀和是递增的,枚举起点,我们不难二分一个"中点"
    中点左边的点距离小于半个周长,右边的点距离大于半个周长,然后用终点顺、逆时针距离最小值更新答案即可。
    复杂度O(nlogn)

    做法2:
    记录前缀和sum,总长度Len
    于是从第一头奶牛开始,找到l,r两只牛,l <= r 这里从1开始
    不难发现当距离小于总长度一半的时候,我们需要去找l, r + 1
    当距离大于总长度一半的时候,我们需要去找l + 1, r 一定优于l + 1, r + 1

    这样省去了很多无用的l,r
    乱搞一下就可以了
    复杂度O(n)

    Code
    第二种做法

    #include <bits/stdc++.h>
    
    const int MAXN = 100000 + 10;
    
    inline void read(int &x){x = 0;char ch = getchar();char c = ch;while(ch > '9' || ch < '0')c = ch, ch = getchar();while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();if(c == '-')x = -x;}
    inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}
    inline int min(int a,int b){return a > b ? b : a;}
    inline int max(int a,int b){return a > b ? a : b;}
    
    int n;
    int sum[MAXN],num[MAXN],len;
    int ans;
    int main()
    {
    	read(n); 
    	for(int i = 2;i <= n;i ++)
    	{
    		read(num[i]);
    		sum[i] = sum[i - 1] + num[i];
    		len += num[i];
    	}
    	read(num[1]);len += num[1];sum[n + 1] = sum[n] + num[1];
    	int l = 1, r = 1;int mid = len >> 1;
    	while(l <= n + 1 && r <= n + 1)
    	{
    		if(l == r)
    		{
    			r ++;
    		}
    		else if(sum[r] - sum[l] <= mid)
    		{
    			ans = max(ans, sum[r] - sum[l]);
    			r ++;
    		}
    		else if(sum[r] - sum[l] > mid)
    		{
    			ans = max(ans, min(sum[r] - sum[l], mid - sum[r] + sum[l]));
    			l ++;
    		}
    	}
    	printf("%d", ans);
        return 0;
    }
    
    第一种做法
    #include <bits/stdc++.h>
    
    const int MAXN = 300000 + 10;
    
    inline void read(int &x){x = 0;char ch = getchar();char c = ch;while(ch > '9' || ch < '0')c = ch, ch = getchar();while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();if(c == '-')x = -x;}
    inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}
    inline int min(int a,int b){return a > b ? b : a;}
    inline int max(int a,int b){return a > b ? a : b;}
    
    int n;
    int sum[MAXN >> 1],len;
    int ans;
    
    inline int erfen(int l, int r, int p)
    {
    	int mid = l + (r - l);
    	while(l < r)
    	{
    		mid = l + ((r - l) >> 1);
    		if(p <= sum[mid])r = mid;
    		else l = mid + 1;
    	}
    	return l;
    }
    
    //枚举起始点i,二分找j,令s[j] - s[i] <= s / 2  这样j 和 j-1  两个点二选一
    //处理环就多复制一层    
    int main()
    {
    	read(n); 
    	for(int i = 1;i <= n;i ++)
    	{
    		read(sum[i]);
    		len += sum[i];
    		sum[i] += sum[i - 1];
    	}
    	for(int i = 1;i <= n;i ++)
    	{
    		 sum[i + n] = len + sum[i];
    	}
    	for(int i = 1;i <= 2 * n;i ++)
    	{
    		int tmp = erfen(1, 2 * n, sum[i] + (len >> 1));
    		ans = max(ans, min(sum[tmp] - sum[i], len - sum[tmp] + sum[i]));
    		ans = max(ans, sum[tmp - 1] - sum[i]) ;
    	}
    	printf("%d", ans);
        return 0;
    }
    
    
    
    





  • 相关阅读:
    WebGL着色器32位浮点数精度损失问题
    Web地图呈现原理
    虚拟DOM详解
    webgl开发第一道坎——矩阵与坐标变换
    作为前端应当了解的Web缓存知识
    浅谈模板引擎
    WebGL中深度碰撞方法总结
    不加班的项目从排期开始
    从0到1带人做项目
    webgl自学笔记——深度监测与混合
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7007532.html
Copyright © 2011-2022 走看看