【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;
}
posted @ 2017-10-04 18:44  AWCXV  阅读(249)  评论(0编辑  收藏  举报