ccf_再卖菜

#include<bits/stdc++.h>
using namespace std;

const int maxn = 300 + 3;
const int maxv = 200;
int n;
int A[maxn], B[maxn];
bool finish;

bool solve(int cur)
{
    if(finish) return true;
    //下面根据 B[cur]所受到的牵连的不同情况进行考虑
    //for中的条件其实也是在剪枝,有的for循环一次循环都没有进行,即在递归的入口处做了手脚。
    if(cur == n + 1){
        finish = true;
        cout << B[1];
        for(int i = 2; i <= n; i++)
            cout << ' ' << B[i];
        cout << endl;
        return true;
    }else if(cur == 1){
        for(int v = 1; v < 2*A[1] + 1; v++){
            if(finish){
                return true;
            }
            B[cur] = v;
            solve(cur + 1);
        }
    }else if(cur == 2){
        int left = 2*A[cur-1] - B[cur-1];
        for(int v = max(1, left); v < left + 2; v++){
            if(finish) return true;
            B[cur] = v;
            solve(cur + 1);
        }
    }else if(cur == n){
        int l1 = 2*A[cur] - B[cur-1], r1 = l1 + 2;
        int l2 = 3*A[cur-1] - B[cur-2] - B[cur-1], r2 = l2 + 3;
        if(r2 <= l1 || l2 >= r1){//no intersect
            return false;
        }else{
            int left = max(l1, l2);
            int right = min(r1, r2);
            for(int v = max(1, left); v < right; v++){
                if(finish) return true;
                B[cur] = v;
                solve(cur + 1);
            }
        }
    }else{
        int left = 3*A[cur-1] - B[cur-2] - B[cur-1];
        for(int v = max(1, left); v < left + 3; v++){
            if(finish) return true;
            B[cur] = v;
            solve(cur + 1);
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    while(cin >> n && n){
        for(int i = 1; i <= n; i++){
            cin >> A[i];
        }
        finish = false;
        solve(1);

    }
    return 0;
}
View Code

以上是回溯解法,超时,只有80分。

posted on 2019-03-07 21:14  nbsanshi  阅读(220)  评论(0编辑  收藏  举报

导航