D - Equal Cut【思维+枚举】

D - Equal Cut

题意:将长为n的序列分成连续的4个非空区间,求出每个区间的和,使得max(区间和)-min(区间和) 最小

思路:割3刀,很自然想到枚举第二刀i,正常做法O(n^3),注定要凉。 我们将区间[1,i-1]划分成2个非空区间L1,L2,为了划分后,使得有:最大值尽可能小,最小值尽可能大,则有L1和L2的差距越小越好。并且有i+1划分时,只需要把i的L1继续使用。对于划分区间[i+1,n]同理

#include<bits/stdc++.h>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int MOD=1e9+7;
ll a[N];
ll sum[N];
//ll ans[N];

ll gao(int l,int r){  //求区间l,r的和
    return sum[r]-sum[l-1];
}

int main(void){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);

    int n ;
    cin >>n;
    for(int i=1;i<=n;i++)   cin >> a[i];
    for(int i=1;i<=n;i++)   sum[i]=sum[i-1]+a[i]; //求前缀和
    ll l=1,r=3;
    ll ans=1e18+8;
    for(int i=2;i<=n-2;i++){
         while(l+1<i&&abs(gao(1,l)-gao(l+1,i))>=abs(gao(1,l+1)-gao(l+2,i)))//若[1,l+1]和[l+1,i]的距离比[1,l+1]和[l+2,i]的距离小,那么我们就继续加,使得两边尽可能平衡
            l++;
         while(r+1<n&&abs(gao(i+1,r)-gao(r+1,n))>=abs(gao(i+1,r+1)-gao(r+2,n)))
            r++;
         set<ll>st;///利用set的log排序
         st.insert(gao(1,l));
         st.insert(gao(l+1,i));
         st.insert(gao(i+1,r));
         st.insert(gao(r+1,n));
         ans=min(ans,abs(*st.begin()-*prev(st.end())));
    }
    cout << ans << endl;

    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我理解了你的问题。以下是Complex类的定义,其中重载了常见的运算符和比较运算符: ```C++ #include<iostream> using namespace std; class Complex { private: double real; double imag; public: Complex(double r=0, double i=0):real(r), imag(i) {} Complex operator+(const Complex& c) const { return Complex(real+c.real, imag+c.imag); } Complex operator-(const Complex& c) const { return Complex(real-c.real, imag-c.imag); } Complex operator*(const Complex& c) const { return Complex(real*c.real-imag*c.imag, real*c.imag+imag*c.real); } Complex operator/(const Complex& c) const { double den = c.real*c.real + c.imag*c.imag; return Complex((real*c.real+imag*c.imag)/den, (imag*c.real-real*c.imag)/den); } Complex& operator+=(const Complex& c) { real += c.real; imag += c.imag; return *this; } Complex& operator-=(const Complex& c) { real -= c.real; imag -= c.imag; return *this; } Complex& operator*=(const Complex& c) { double r = real*c.real - imag*c.imag; double i = real*c.imag + imag*c.real; real = r; imag = i; return *this; } Complex& operator/=(const Complex& c) { double den = c.real*c.real + c.imag*c.imag; double r = (real*c.real + imag*c.imag)/den; double i = (imag*c.real - real*c.imag)/den; real = r; imag = i; return *this; } bool operator==(const Complex& c) const { return (real==c.real) && (imag==c.imag); } bool operator!=(const Complex& c) const { return !(*this == c); } friend ostream& operator<<(ostream& os, const Complex& c); }; ostream& operator<<(ostream& os, const Complex& c) { os << "(" << c.real << "," << c.imag << ")"; return os; } ``` 在这个类中,我们定义了构造函数,以便我们可以使用默认参数或传递实部和虚部来创建Complex对象。 我们重载了加、减、乘、除、+=、-=、*=、/= 运算符,并且我们还重载了比较运算符 == 和 !=。我们还定义了一个友元函数,用于将Complex对象输出到标准输出流中。 您可以使用此类来执行各种操作。以下是一些示例: ```C++ Complex a(1, 2), b(3, 4); Complex c = a + b; // c = (4, 6) Complex d = a - b; // d = (-2, -2) Complex e = a * b; // e = (-5, 10) Complex f = a / b; // f = (0.44, 0.08) a += b; // a = (4, 6) b -= a; // b = (-1, -2) c *= d; // c = (20, 0) d /= e; // d = (0.08, -0.16) bool equal = (a == b); // equal = false bool not_equal = (a != b); // not_equal = true cout << a << " " << b << " " << c << " " << d << endl; // 输出 (4,6) (-1,-2) (20,0) (0.08,-0.16) ``` 希望这可以回答您的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值