搜索

7 篇文章 0 订阅
6 篇文章 0 订阅

noip2015 斗地主

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int t, n, ans;
int cnt[20];

void dfs ( int s, int k ) {
    if ( k > ans ) return ; //最优性剪枝
    if ( s == 0 ) {
        if ( k < ans ) ans = k;
        return ;
    }
    int sum = 0;
    for ( int i = 2; i <= 14; i ++ )
        if ( cnt[i] ) sum ++;
    if ( cnt[0] ) sum ++;
    ans = min ( ans, k+sum );
    for ( int i = 3; i <= 10; i ++ ) { //搜索顺序的改变:优先扩张顺子(情况少)
        if ( cnt[i] ) {
            bool flag = 1;
            for ( int j = i+1; j <= i+4; j ++ )
                if ( !cnt[j] ) { flag = 0; break; }
            if ( !flag ) continue;

            for ( int j = i+4; j <= 14 && cnt[j]; j ++ ) {
                for ( int p = i; p <= j; p ++ ) cnt[p] --;
                dfs ( s-(j-i+1), k+1 );
                for ( int p = i; p <= j; p ++ ) cnt[p] ++;
            }
        }
    }
    for ( int i = 3; i <= 12; i ++ ) {
        if ( cnt[i] >= 2 ) {
            bool flag = 1;
            for ( int j = i+1; j <= i+2; j ++ )
                if ( cnt[j] < 2 ) { flag = 0; break; }
            if ( !flag ) continue;
            for ( int j = i+2; j <= 14 && cnt[j] >= 2; j ++ ) {
                for ( int p = i; p <= j; p ++ ) cnt[p] -= 2;
                dfs ( s-2*(j-i+1), k+1 );
                for ( int p = i; p <= j; p ++ ) cnt[p] += 2;
            }
        }
    }
    for ( int i = 3; i <= 13; i ++ ) {
        if ( cnt[i] >= 3 && cnt[i+1] >= 3 ) {
            for ( int j = i+1; j <= 14 && cnt[j] >= 3; j ++ ) {
                for ( int p = i; p <= j; p ++ ) cnt[p] -= 3;
                dfs ( s-3*(j-i+1), k+1 );
                for ( int p = i; p <= j; p ++ ) cnt[p] += 3;
            }
        }
    }
    for ( int i = 2; i <= 14; i ++ ) {
        if ( cnt[i] >= 3 ) {
            cnt[i] -= 3;
            for ( int j = 0; j <= 14; j ++ ) {
                if ( cnt[j] ) {
                    cnt[j] --;
                    dfs ( s-4, k+1 );
                    cnt[j] ++;
                }
                if ( cnt[j] >= 2 ) {
                    cnt[j] -= 2;
                    dfs ( s-5, k+1 );
                    cnt[j] += 2;
                }
            }
            dfs ( s-3, k+1 );
            cnt[i] += 3;
        }
    }
    for ( int i = 2; i <= 14; i ++ ) {
        if ( cnt[i] >= 4 ) {
            cnt[i] -= 4;
            for ( int j = 0; j <= 14; j ++ ) {
                if ( cnt[j] ) {
                    cnt[j] --;
                    for ( int p = j+1; p <= 14; p ++ ) {
                        if ( cnt[p] ) {
                            cnt[p] --;
                            dfs ( s-6, k+1 );
                            cnt[p] ++;
                        }
                    }
                    cnt[j] ++;
                }
                if ( cnt[j] >= 2 ) {
                    cnt[j] -= 2;
                    for ( int p = j+1; p <= 14; p ++ ) {
                        if ( cnt[p] >= 2 ) {
                            cnt[p] -= 2;
                            dfs ( s-8, k+1 );
                            cnt[p] += 2;
                        }
                    }
                    cnt[j] += 2;
                }
            }
            dfs ( s-4, k+1 );
            cnt[i] += 4;
        }
    }
}

int main ( ) {
    freopen ( "landlords.in", "r", stdin );
    freopen ( "landlords.out", "w", stdout );
    scanf ( "%d%d", &t, &n );
    for ( int tt = 1; tt <= t; tt ++ ) {
        memset ( cnt, 0, sizeof ( cnt ) );
        ans = 0x3f3f3f3f;
        for ( int i = 1; i <= n; i ++ ) {
            int x, y;
            scanf ( "%d%d", &x, &y );
            if ( x == 1 ) x += 13;
            cnt[x]++;
        }
        dfs ( n, 0 );
        printf ( "%d\n", ans );
    }

    return 0;
}

双向广搜

普通bfs的修改:

poj1915 模板练习
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

const int zl[10][10] = {{0,0},{-1,-2},{-1,2},{-2,-1},{-2,1},{2,-1},{2,1},{1,2},{1,-2}};

int n, sx, sy, tx, ty;

struct node {
    int x, y;
    node ( int x, int y ) : x ( x ), y ( y ) { }
};
queue < node > q;
int flag[505][505], dis[505][505];

int BFS ( ) {
    memset ( flag, 0, sizeof ( flag ) );
    memset ( dis, 0, sizeof ( dis ) );
    while ( !q.empty ( ) ) q.pop ( );
    q.push ( node ( sx, sy ) ); q.push ( node ( tx, ty ) ); //起点终点同时入队一起走
    flag[sx][sy] = 1; flag[tx][ty] = 2; //起点标记与终点不同
    while ( !q.empty ( ) ) {
        node a = q.front ( ); q.pop ( );
        int x = a.x, y = a.y;
        for ( int i = 1; i <= 8; i ++ ) {
            int xx = x + zl[i][0], yy = y + zl[i][1];
            if ( xx > n || yy > n || xx <= 0 || yy <= 0 ) continue;
            if ( flag[x][y] != flag[xx][yy] && flag[x][y] && flag[xx][yy] ) //走到一样的子状态
                return dis[x][y] + dis[xx][yy] + 1;
            if ( !flag[xx][yy] ) {
                q.push ( node ( xx, yy ) );
                dis[xx][yy] = dis[x][y] + 1;
                flag[xx][yy] = flag[x][y];
            }
        }
    }
    return 0;
}

int main ( ) {
    int T;
    scanf ( "%d", &T );
    while ( T -- ) {
        scanf ( "%d", &n );
        scanf ( "%d%d%d%d", &sx, &sy, &tx, &ty );
        sx ++; sy ++; tx ++; ty ++;
        int ans = BFS ( );
        printf ( "%d\n", ans );
    }

    return 0;
}

练习:hdu3085(几乎裸)

poj3523

恶心题 不知道哪错了aaaa!!

8.12更新:)
无fuck说:):):)见代码

//A* 双广
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define QWQ short int
using namespace std;

const int zl[5][2] = {{0,0},{0,1},{0,-1},{-1,0},{1,0}};

QWQ sax, say, sbx, sby, scx, scy, tax, tay, tbx, tby, tcx, tcy;
QWQ opt[5];
int H, W, n;
QWQ G[21][21], dis[3][17][17];
QWQ f[17][17][17][17][17][17];
char map[21][21];

struct prenode {
    QWQ x, y;
    prenode ( QWQ x, QWQ y ) : x (x), y (y) { }
};

bool check ( int x, int y ) {
    if ( x <= 0 || y <= 0 || x > H || y > W || map[x][y] == '#' ) return 1;
    return 0;
}

void pre_count ( int opp ) {
    queue < prenode > q;
    QWQ sx, sy;
    char des = 'A' + opp;
    if ( des == 'A' ) sx = tax, sy = tay;
    if ( des == 'B' ) sx = tbx, sy = tby;
    if ( des == 'C' ) sx = tcx, sy = tcy;
    dis[opp][sx][sy] = 0;
    q.push ( prenode ( sx, sy ) );
    while ( !q.empty ( ) ) {
        prenode u = q.front ( ); q.pop ( );
        QWQ x = u.x, y = u.y;
        for ( int i = 1; i <= 4; i ++ ) {
            QWQ xx = x + zl[i][0], yy = y + zl[i][1];
            if ( check ( xx, yy ) ) continue;
            if ( dis[opp][xx][yy] > dis[opp][x][y] + 1 ) {
                dis[opp][xx][yy] = dis[opp][x][y] + 1;
                q.push ( prenode ( xx, yy ) );
            }
        }
    }
}

void init ( ) {
    sax = say = sbx = sby = scx = scy = tax = tay = tbx = tby = tcx = tcy = 0;
    memset ( opt, 0, sizeof ( opt ) );
    memset ( dis, 4, sizeof ( dis ) );
    memset ( map, 0, sizeof ( map ) );
    memset ( f, 4, sizeof ( f ) );
    gets ( map[0] );
    for ( int i = 0; i < H; i ++ )
        gets ( map[i] );
    for ( int i = 0; i < H; i ++ ) {
        for ( int j = 1; j < W; j ++ ) {
            if ( map[i][j] == 'a' ) sax = i, say = j;
            else if ( map[i][j] == 'b' ) sbx = i, sby = j;
            else if ( map[i][j] == 'c' ) scx = i, scy = j;
            else if ( map[i][j] == 'A' ) tax = i, tay = j, opt[0] = 1;
            else if ( map[i][j] == 'B' ) tbx = i, tby = j, opt[1] = 1;
            else if ( map[i][j] == 'C' ) tcx = i, tcy = j, opt[2] = 1;
        }
    }
}

QWQ predict_h ( QWQ ax, QWQ ay, QWQ bx, QWQ by, QWQ cx, QWQ cy ) {
    return max ( dis[0][ax][ay], max ( dis[1][bx][by], dis[2][cx][cy] ) );
}

struct node {
    QWQ ax, ay, bx, by, cx, cy, g, h; //g为距起点最短路 h为到终点的估值 
    node ( QWQ ax, QWQ ay, QWQ bx, QWQ by, QWQ cx, QWQ cy, QWQ g, QWQ h ):
            ax (ax), ay (ay), bx (bx), by (by), cx (cx), cy (cy), g (g), h (h) {}
    bool operator < ( const node & a ) const {
        return g + h > a.g + a.h;
    }
};

void A_star ( ) {
    priority_queue < node > que;
    que.push ( node ( sax, say, sbx, sby, scx, scy, 0, predict_h ( sax, say, sbx, sby, scx, scy ) ) );
    f[sax][say][sbx][sby][scx][scy] = predict_h ( sax, say, sbx, sby, scx, scy );
    QWQ ax = 0, ay = 0, bx = 0, by = 0, cx = 0, cy = 0;
    while ( !que.empty ( ) ) {
        ax = ay = bx = by = cx = cy = 0;
        node cur = que.top ( ); que.pop ( );
        if ( cur.g + cur.h > f[cur.ax][cur.ay][cur.bx][cur.by][cur.cx][cur.cy] ) continue;
        if ( cur.ax == tax && cur.ay == tay && cur.bx == tbx && cur.by == tby && cur.cx == tcx && cur.cy == tcy ) {
            printf ( "%d\n", cur.g );
            return ;
        }
        for ( int i = 0; i <= 4; i ++ ) {
            if ( opt[0] ) {
                ax = cur.ax + zl[i][0]; ay = cur.ay + zl[i][1];
                if ( check ( ax, ay ) ) continue;
            }
            for ( int j = 0; j <= 4; j ++ ) {
                if ( opt[1] ) {
                    bx = cur.bx + zl[j][0]; by = cur.by + zl[j][1];
                    if ( check ( bx, by ) ) continue;
                    if ( bx == ax && by == ay ) continue;
                    if ( ax == cur.bx && bx == cur.ax && ay == by ) continue;
                    if ( ay == cur.by && by == cur.ay && ax == bx ) continue;
                }
                for ( int k = 0; k <= 4; k ++ ) {
                    if ( opt[2] ) {
                        cx = cur.cx + zl[k][0]; cy = cur.cy + zl[k][1];
                        if ( check ( cx, cy ) ) continue;
                        if ( (cx == ax && cy == ay) || (cx == bx && cy == by) ) continue;
                        if ( cx == cur.bx && bx == cur.cx && cy == by ) continue;
                        if ( cx == cur.ax && ax == cur.cx && cy == ay ) continue;
                        if ( cy == cur.by && by == cur.cy && cx == bx ) continue; 
                        if ( cy == cur.ay && ay == cur.cy && cx == ax ) continue;
                    }
                    QWQ pre_h = predict_h ( ax, ay, bx, by, cx, cy );
                    if ( cur.g + 1 + pre_h < f[ax][ay][bx][by][cx][cy] ) {
                        f[ax][ay][bx][by][cx][cy] = cur.g + 1 + pre_h;
                        que.push ( node ( ax, ay, bx, by, cx, cy, cur.g+1, pre_h ) );
                    }
                }
            }
        }
    }
    return ;
}

int main ( ) {
    while ( scanf ( "%d%d%d", &W, &H, &n ) != EOF && W && H && n ) {
        init ( );
        for ( QWQ i = 0; i < 3; i ++ )
            if ( opt[i] ) pre_count ( i );
            else memset ( dis[i], 0, sizeof ( dis[i] ) );//错了两个月是因为括号里dis没写[i]你敢信??
        A_star ( );
    }
    return 0;
}

迭代加深搜索(IDFS)

%%%

经典题:埃及分数 (IDA*)

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;

ll mu[10005], ans[10005], maxd;

bool check ( ll dep ) {
    for ( ll d = dep; d >= 0; d -- )
        if ( mu[d] != ans[d] ) return ans[d] == -1 || mu[d] < ans[d];
    return 0;
}

ll gcd ( ll a, ll b ) {
    return b == 0 ? a : gcd ( b, a % b );
}

bool dfs ( ll dep, ll nex_mu, ll a, ll b ) {
    bool flag;
    if ( dep == maxd ) {
        if ( b % a ) return 0;
        mu[dep] = b / a;
        if ( check ( dep ) ) memcpy ( ans, mu, sizeof (ll) * ( dep+1 ) );
        return true;
    }
    flag = 0;
    nex_mu = max ( nex_mu, b/a+1 ); // 满足a/b的最小分母为b/a+1 
    for ( int i = nex_mu; ; i ++ ) {
        if ( (maxd-dep+1) * b <= i * a ) break; // if ( (maxd-dep+1)/i <= a/b ) break;//A*关键部分
        mu[dep] = i;
        ll b2 = b * i;
        ll a2 = a * i - b;
        ll qwq = gcd ( a2, b2 );
        if ( dfs ( dep+1, i+1, a2/qwq, b2/qwq ) ) flag = true;
    }
    return flag;
}

int main ( ) {
    int a, b;
    scanf ( "%d%d", &a, &b );
    bool fl = 0;
    for ( maxd = 1; ; maxd ++ ) {//枚举深度上界
        memset ( ans, -1, sizeof ( ans ) );
        if ( dfs ( 0, b/a+1, a, b ) ) {
            fl = 1; break;
        }
    }
    if ( fl ) {
        for ( int i = 0; i < maxd; i ++ )
            printf ( "1/%lld+", ans[i] );
        printf ( "1/%lld\n", ans[maxd] );
    } else {
        printf ( "no answer!\n" );
    }
}

poj2286 The Rotation Game

依旧不知道哪里错了aaaaaaaaaaaaaaaaaaaaaaa
8.13更新!!!结果是审题问题!!不管用不用移动最后都要输出line[matrix[0]]!!(为什么搜索题总是main函数里面错aaaa!!

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int line[30], maxd;
char mu[1005];

int lines[10][10]={ // A(0) <-> F(5) B(1) <-> E(4) C(2) <-> H(7) D(3) <-> G(6)
                   { 0, 2, 6,11,15,20,22},// A
                   { 1, 3, 8,12,17,21,23},// B
                   {10, 9, 8, 7, 6, 5, 4},// C
                   {19,18,17,16,15,14,13},// D
                   {23,21,17,12, 8, 3, 1},//E
                   {22,20,15,11, 6, 2, 0},//F
                   {13,14,15,16,17,18,19},//G
                   {4, 5, 6, 7, 8, 9, 10},//H
                  };

int matrix[10] = { 6, 7, 8, 11, 12, 15, 16, 17 };

int predict ( ) {
    int maxx = 0x3f3f3f3f;
    for ( int i = 1; i <= 3; i ++ ) {
        int res = 0;
        for ( int j = 0; j < 8; j ++ )
            if ( line[matrix[j]] != i ) res ++;
        maxx = min ( res, maxx );
    }
    return maxx;
}

bool check ( ) {
    for ( int i = 0; i < 8; i ++ )
        if ( line[matrix[i]] != line[matrix[0]] ) return 0;
    return 1;
}

void rot ( int i ) {
    int yr = line[lines[i][0]];
    for ( int j = 0; j < 6; j ++ ) 
        line[lines[i][j]] = line[lines[i][j+1]];
    line[lines[i][6]] = yr;
}

bool IDFS ( int dep ) {
    if ( dep == maxd ) return check ( ); 
    if ( dep + predict ( ) > maxd ) return 0;
    for ( int i = 0; i < 8; i ++ ) {
        mu[dep] = i + 'A';
        rot ( i );
        if ( IDFS ( dep+1 ) ) return 1;
        if ( i % 2 == 0 ) rot ( ( i + 5 ) % 8 );
        else rot ( ( i + 3 ) % 8 );
    }
    return 0;
}

int main ( ) {
    while ( scanf ( "%d", &line[0] ) != EOF && line[0] != 0 ) {
        for ( int i = 1; i < 24; i ++ )
            scanf ( "%d", &line[i] );
        if ( check ( ) ) {
            printf ( "No moves needed\n" );
        }
        else {
            for ( maxd = 1; ; maxd ++ ) {
                if ( IDFS ( 0 ) ) break;
            }
            mu[maxd] = '\0';
            printf ( "%s\n", mu );
        }
        printf ( "%d\n", line[matrix[0]] );
    }
    return 0;
}

A*算法

%%%

k短路

//k短路 A*算法 无向图 
//f = h + g h为距起点的估值 g为距终点的最小值 

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>

#define oo 0x3f3f3f3f
using namespace std; 

struct matrix { //邻接矩阵存图 
    int v, w;
    matrix ( int v, int w ) : v ( v ), w ( w ) { }
};
vector < matrix > G[N];

void add ( int u, int v, int s ) {
    G[u].push ( matrix ( v, s ) );
    G[v].push ( matrix ( u, s ) ); 
}

queue < int > q;
int g[N], vis[N];

void spfa ( ) { //反向跑spfa处理出g
    memset ( g, 0x3f3f3f3f, sizeof ( g ) );
    q.push ( t );
    vis[t] = 1; g[t] = 0;       
    while ( !q.empty ( ) ) {
        int u = q.front ( ); q.pop ( ); vis[u] = 0;
        for ( int i = 0; i < G[u].size ( ); i ++ ) {
            int v = G[u][i].v;
            if ( g[v] > g[u] + G[u][i].w ) {
                g[v] = g[u] + G[u][i].w;
                if ( !vis[v] ) {
                    vis[v] = 1;
                    q.push ( v );
                }
            }
        }
    }
}

struct node {
    int u, h;
    node ( int u, int h ) : u ( u ), h ( h ) { }
    bool operator < ( const node a ) const {
        return h + g[u] > a.h + g[a.u];
    }
}; 
priority_queue < node > que;

int A_star ( ) {
    if ( g[s] == oo ) return -1;
    que.push ( node ( s, 0 ) );
    while ( !que.empty ( ) ) {
        node a = que.top ( ); que.pop ( );
        int u = a.u, h = a.h;
        cnt[u] ++;
        if ( cnt[t] == K ) return h; //第k次到终点 
        for ( int i = 0; i < G[u].size ( ); i ++ ) {
            int v = G[u][i].v;
            que.push ( node ( v, h + G[u][i].w ) ); //每个估值都要存入排序 
        } 
    }
}

[SDOI2010]魔法猪学院

然而数据加强了目前T一个点

//k短路 A*算法 有向图 
//f = h + g h为距起点的估值 g为距终点的最小值 

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#define RG register

#define oo 0x3f3f3f3f
using namespace std;

const int N = 5005;

int n, m, s, t, ans;
double k;

struct matrix {
    int v;
    double w;
    matrix ( int v, double w ) : v ( v ), w ( w ) { }
};
vector < matrix > G[N];
vector < matrix > G1[N];

void add ( int u, int v, double s ) {
    G[u].push_back ( matrix ( v, s ) );
    G1[v].push_back ( matrix ( u, s ) ); 
}
double g[N];
int vis[N];

void spfa ( ) {
    for ( RG int i = 1; i < N; i ++ )
        g[i] = oo;
    queue < int > q;
    q.push ( t );
    vis[t] = 1; g[t] = 0;       
    while ( !q.empty ( ) ) {
        int u = q.front ( ); q.pop ( ); vis[u] = 0;
        for ( RG int i = 0; i < G1[u].size ( ); i ++ ) {
            int v = G1[u][i].v;
            if ( g[v] > g[u] + G1[u][i].w ) {
                g[v] = g[u] + G1[u][i].w;
                if ( !vis[v] ) {
                    vis[v] = 1;
                    q.push ( v );
                }
            }
        }
    }
}

struct node {
    int u;
    double h;
    node ( int u, double h ) : u ( u ), h ( h ) { }
    bool operator < ( const node a ) const {
        return h + g[u] > a.h + g[a.u];
    }
}; 
priority_queue < node > que;

int cnt[N];

void A_star ( ) {
    double all = k / g[s]; //优化每个点最多经过次数
    que.push ( node ( s, 0 ) );
    while ( !que.empty ( ) ) {
        node a = que.top ( ); que.pop ( );
        int u = a.u;
        double h = a.h;
        if ( h > k ) return ;
        cnt[u] ++;
        if ( cnt[u] > all ) continue;
        if ( u == t ) {
            k -= h; ans ++; continue;
        }
        for ( RG int i = 0; i < G[u].size ( ); i ++ ) {
            int v = G[u][i].v;
            que.push ( node ( v,  1.0 * ( h + G[u][i].w ) ) );
        }
    }
}

int main ( ) {
    scanf ( "%d%d%lf", &n, &m, &k );
    s = 1, t = n;
    for ( RG int i = 1; i <= m; i ++ ) {
        int u, v;
        double l;
        scanf ( "%d%d%lf", &u, &v, &l );
        add ( u, v, l );
    }
    spfa ( );
    A_star ( );
    printf ( "%d", ans );
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值