hdu 1518||poj 2362 Square(dfs)

小記:這題看重的是剪枝,但是都後來發現,其實這應該是一個當初的想法錯誤,導致的TLE


思路:dfs,一條邊一條邊的dfs,當能dfs出3條邊時,就是yes。當然最開始應該判斷%4是否等於0對於總長度。

而dfs的順序就是從大到小,這點算是剪枝吧,可以少很多工作。

當沒組成一條邊時,就從大到小搜,一直往小的搜,

而當組成了一條邊的時候就要從頭開始搜。因爲沒組成時,可能出現加起來大於一條邊的長度的。


我之前wa就出錯在沒組成一條邊,我也是從頭開始搜,唉~愚鈍!


代碼:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 1010;
const int N = 100010;
const int INF = 0x7fffffff;

int C[MAX_];
char str[MAX_][MAX_];
int a[MAX_];
int vis[MAX_];

int n, m, avg;

int dir[4][2] = {{0,-1},{-1,0},{0,1},{1,0}};
int dfs(int sum[], int x)
{

    bool flag = 0;
    REP(i, 0, 4){
        if(sum[i] != avg){flag = 1;break;}
    }
    if(!flag) return 1;

    if(x >= n)return 0;

    flag = 0;
    int i = x;
    //REP(i, x, n){
        if(!vis[i]){
            REP(j, 0, 4){
                if(sum[j] + a[i] <= avg ){
                    if(sum[j] == 0 && flag)continue;
                    sum[j] += a[i];
                    int tmp = dfs(sum, x+1);
                    if(tmp)return 1;
                    sum[j] -= a[i];
                    if(sum[j] == 0)flag = 1;
                }
            }
        }
    //}
    return 0;
}


int dfs1(int sum, int x,int cur)
{
    if(x == 3)return 1;
    //printf("%d %d ok\n",sum, x);
    REP(i, cur, n){
        if(!vis[i]){

            if(sum + a[i] == avg){
                vis[i] = 1;
                int tmp = dfs1(0, x+1, 0);
                if(tmp == 1)return 1;
                vis[i] = 0;
            }
            else if(sum + a[i] < avg){
                vis[i] = 1;
                int tmp = dfs1(sum + a[i], x, i);
                if(tmp == 1) return 1;
                vis[i] = 0;
            }
        }
    }
    return 0;
}

bool cmp(const int a, const int b)
{
    return a > b;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T-- &&scanf("%d", &n)){
        int sum = 0;
        REP(i, 0, n){
            scanf("%d",&a[i]);
            sum += a[i];
        }
        sort(a, a+n, cmp);
        if(sum%4 != 0 || n < 4 || a[0] > sum/4){
            printf("no\n");
            continue;
        }
        avg = sum/4;
        mst(vis, 0);
        int ss[4];
        mst(ss, 0);

        int ans = dfs1(0, 0, 0);//(ss, 0);

        if(ans){
            printf("yes\n");
        }else {
            printf("no\n");
        }

    }
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章