zoukankan      html  css  js  c++  java
  • 【codeforces 257D】Sum

    【题目链接】:http://codeforces.com/problemset/problem/257/D

    【题意】

    给你n个数字;
    这n个数字组成的数组满足:
    a[i-1]<=a[i]<=2*a[i-1]
    让你确定每个数字的符号(正或负);
    然后把所有的数字都加起来;
    把和记为s;
    需要满足0<=s<=a[1];

    【题解】

    记最后一个数字的符号为+
    然后sum=a[n]
    由a[i]<=2*a[i-1]
    可以得到
    a[i]-a[i-1]<=a[i-1]
    则让sum去减a[i-1];
    可以保证0<=sum<=a[i-1];
    然后再往前想;
    假设再让sum-a[i-2];
    则sum<=a[i-1]<=2*a[i-2]
    则sum-a[i-2]<=a[i-2]
    即也能满足|sum|<=a[i-2];
    只不过此时不能保证sum大于等于0了;
    但如果此时sum是小于0的;
    我们完全可以把刚才选择的所有符号都取反;
    这时就能保证sum小于等于a[i-2]且sum>=0了;
    然后sum<=a[i-2]<=2*a[i-3]…
    sum-a[i-3]<=a[i-3]….
    以此类推;
    当然,我们在减的时候,遇到sum<0的情况时;
    可以先不用把之前选择的符号取反;
    可以把减法改成加法;
    这样取反之后就还是减法了;
    等最后,发现还是小于0;
    再一次性把所有的符号都取反;

    【Number Of WA

    0

    【反思】

    光想着从前往后推了;
    没想到从后往前推会比较好想一些.
    这个式子从后往前模拟比较容易得到思路;
    思维还是太局限了;
    要往多方面想。

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ms(x,y) memset(x,y,sizeof x)
    #define Open() freopen("F:\rush.txt","r",stdin)
    #define Close() ios::sync_with_stdio(0)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 1e5+100;
    
    int n,ans[N];
    LL a[N];
    
    int main(){
        //Open();
        Close();
        cin >> n;
        rep1(i,1,n){
            cin >> a[i];
        }
        LL temp = a[n];
        ans[n] = 1;
        rep2(i,n-1,1){
            if (temp > 0){
                temp-=a[i];
                ans[i] = 0;
            }else{
                temp+=a[i];
                ans[i] = 1;
            }
        }
        if (temp < 0){
            rep1(i,1,n)
                ans[i]^=1;
        }
        rep1(i,1,n)
            if (ans[i]){
                cout <<'+';
            }else{
                cout <<'-';
            }
        cout << endl;
        return 0;
    }
    
  • 相关阅读:
    linux安装软件的几种方式
    linux目录
    linux远程连接
    linux分区
    linux特殊符号
    sed
    rest_framework认证流程
    一些面试题目
    算法之二分法
    算法之动态规划
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626242.html
Copyright © 2011-2022 走看看