[usaco]1.5 Checker Challenge

来源:互联网 发布:淘宝 小风悦萌 显卡吧 编辑:程序博客网 时间:2024/05/03 22:06

拿到题目我的第一反应是八皇后问题,顺利的写出了递归解法,弄完这个,感觉自己写递归和回溯有了一定的进步了,至此第一章做完了,再接再厉。

但是提交后,在13 这个测试样例超时,然后就在想怎么剪枝

  • 之前在判断放棋子是否冲突的时候,是在放的位置往四个方向拓展,如果没有冲突就放 。现在改进为直接判断 和之前放置的棋子是否冲突。
  • 对称剪枝,这个在百度之后才知道的 ,这个是关键,直接砍掉一般的时间
还有说是用位运算,这个不熟,下次去学一下。
Executing...Test 1: TEST OK [0.000 secs, 3340 KB]Test 2: TEST OK [0.000 secs, 3340 KB]Test 3: TEST OK [0.000 secs, 3340 KB]Test 4: TEST OK [0.011 secs, 3340 KB]Test 5: TEST OK [0.011 secs, 3340 KB]Test 6: TEST OK [0.043 secs, 3340 KB]Test 7: TEST OK [0.162 secs, 3340 KB]Test 8: TEST OK [0.670 secs, 3340 KB]
/*ID:fuxiang2PROG: checkerLANG: C++*/#include <iostream>#include <fstream>#include <stack>#include <string>#include <vector>#include <queue>#include <map>#include <list>#include <algorithm>#include <set>#include <cmath>#include <cstring>#include <cstdlib> #define REP(i, n) for (int i=0;i<int(n);++i)#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)#define REP_1(i, n) for (int i=1;i<=int(n);++i)#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)#define EACH(it, A) for (typeof(A.begin()) it=A.begin(); it != A.end(); ++it) using namespace std;ofstream fout ("checker.out");ifstream fin ("checker.in"); const int N = 14;int graph[N][N];int n;int ans ;int result ;// 类似八皇后问题int used[N];//list <int >path;int path[N]; bool isok(int x,int y){    if(x >=1 && x<= n && y >= 1 && y <= n)        return true;    return false;}int dir[4][2] = { {-1,-1} ,{-1,1},{1,1},{1,-1} };bool check(int x,int y ){    int nx = x;    int ny = y;    int n = x -1;    if(n == 0)        return true;     FOR_1(i,1,n){        nx = i;        ny = path[i];        if( abs(x-nx) == abs(y-ny))            return false;    }    return true;     //FOR_1(i,0,3){    //    nx = x +  dir[i][0];    //    ny = y +  dir[i][1];    //    while(isok(nx,ny) ){    //        if(graph[nx][ny] == 1)    //            return false;    //        nx += dir[i][0];    //        ny += dir[i][1];    //    }    //}    //return true; } void place(int col,int row){    graph[row][col] = 1;    if(row== n){        ans ++;        if(result + ans <= 3){            //list<int >::iterator iter = path.begin();            //fout<< *iter;            fout<<path[1];            //for(iter ++ ; iter != path.end() ; iter ++)            for(int i = 2 ; i <= n ; i ++)                fout <<" "<< path[i];            fout<<endl;        }        graph[row][col] = 0;        return ;    }    FOR_1(i,1,n){        if(used[i] == 0 && check(row+1,i ) == true )        {            path[row+1] = i;//path.push_back(i);            used[i] = 1;            place(i,row+1);            //path.pop_back();            used[i] = 0;        }    }    graph[row][col] = 0; }void work(int n){    result = 0;     FOR_1(j,1,n/2) {// 列        path[1] = j;//path.push_back(j);        used[j]  = 1;        place(j,1);        //path.pop_back();        used[j] = 0;    }    int re =  ans;    result = ans;    if(re <3 || n%2 == 1){        int t = n/2 + 1;        ans = 0;        path[1] = t;//path.push_back(j);        used[t]  = 1;        place(t,1);     }    if( n% 2 == 1)        result += re + ans;    else        result += re;} int main(){    fin>>n;    work(n);    fout<< result<<endl;    return 0; }

原始博客地址: http://www.fuxiang90.com/2012/07/usaco1-5-checker-challenge/