A* IDA*

HDU 1667  IDA* http://acm.hdu.edu.cn/showproblem.php?pid=1667

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

int old[8][7]={
    0,1,2,3,4,5,6,
    7,8,9,10,11,12,13,
    18,17,9,16,2,15,14,
    23,22,11,21,4,20,19,
    13,12,11,10,9,8,7,
    6,5,4,3,2,1,0, 19,
    20,4,21,11,22,23,
    14,15,2,16,9,17,18 };

int mid[8]={2,16,9,3,10,4,21,11};
int w[8]={5,4,7,6,1,0,3,2};
int sta[24];
int na[8][2],nb[3][3];

inline int h(int *p,int k){
    int num=0;
    for(int i=0;i<8;i++)
        if(p[mid[i]]!=k)
            num++;
    return num;
}

inline void getnM(int *p,int k){
    int news=p[old[k][0]];
    for(int i=0;i<6;i++) p[old[k][i]]=p[old[k][i+1]];
    p[old[k][6]]=news;
}
long long u[10];
int M[24];
void IDA(int dis,int num,long long &mmin,int g,long long ans){
    int H=h(M,num);
    if(H==0){
        mmin=min(mmin,ans);
        return ;
    }
    if(H+g>dis) return ;
    
    for(int i=0;i<8;i++){
        if(mmin!=1LL<<40) return;
        getnM(M,i);
        IDA(dis,num,mmin,g+1,ans*10+i);
        getnM(M,w[i]);
    }
}
int ch[24]={0,2,6,11,15,20,22,1,3,8,12,17,21,23,4,5,7,9,10,13,14,16,18,19};

inline void Change(int *p,int *np){
    for(int i=0;i<24;i++)
        np[i]=p[ch[i]];
}

inline void Printf(long long u,int dis){
    if(dis==0) return;
    Printf(u/10,dis-1);
    int v=u%10;
    printf("%c",v+'A');
}

int main(){
    int nsta[26];
    u[0]=1;
    for(int i=0;i<10;i++)
        u[i]=u[i-1]*10;
    while(scanf("%d",&nsta[0]),nsta[0]!=0){
        for(int i=1;i<24;i++)
            scanf("%d",&nsta[i]);
        Change(nsta,M);
        long long int mmin[4];
        int dis[4];
        bool sign=0;
        
        for(int k=0;k<20;k++){
            if(sign) break;
            mmin[0]=mmin[1]=mmin[2]=mmin[3]=1LL<<40;
            for(int i=1;i<=3;i++){
                IDA(k,i,mmin[i],0,0);
                if(mmin[i]!=1LL<<40){
                    dis[i]=k;
                    sign=1;
                }
            }
        }
        
        int mark=1;
        for(int i=1;i<=3;i++)
            if(mmin[mark]>mmin[i]) mark=i;
        if(dis[mark]==0){
            printf("No moves needed\n");
            printf("%d\n",mark);
        }
        else{
            Printf(mmin[mark],dis[mark]);
            printf("\n%d\n",mark);
        }
    }
}


HDU 2234 IDA* http://acm.hdu.edu.cn/showproblem.php?pid=2234


#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int old[16][4]={
    0,1,2,3,    3,2,1,0,
    4,5,6,7,    7,6,5,4,
    8,9,10,11,  11,10,9,8,
    12,13,14,15,15,14,13,12,
    0,4,8,12,   12,8,4,0,
    1,5,9,13,   13,9,5,1,
    2,6,10,14,  14,10,6,2,
    3,7,11,15,  15,11,7,3,};
int M[16];
int h(int *p){
    int r[4][4],c[4][4];
    memset(r,0,sizeof(r));
    memset(c, 0, sizeof(c));
    for(int i=0;i<16;i++){r[i/4][M[i]-1]=1;c[i%4][M[i]-1]=1;}
    int mmaxr=0,mmaxc=0;
    for(int i=0;i<4;i++)
        for(int j=1;j<4;j++){
            r[i][j]+=r[i][j-1];
            c[i][j]+=c[i][j-1];
        }
    for(int j=0;j<4;j++) mmaxr=max(mmaxr,r[j][3]),mmaxc=max(mmaxc,c[j][3]);
    mmaxr--; mmaxc--;
    return min(mmaxc,mmaxr);
}

void getnM(int *p,int k){
    int news;
    news=p[old[k][0]];
    for(int i=0;i<3;i++)
        p[old[k][i]]=p[old[k][i+1]];
    p[old[k][3]]=news;
}

int ans;

int IDA(int dis,int g){
    int H=h(M);
    if(g+H>dis) return 0;
    if(H==0) {ans=g;return 1;}
    for(int i=0;i<16;i++){
        getnM(M, i);
        if(IDA(dis,g+1)) return 1;
        getnM(M, i^1);
    }
    return 0;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        for(int i=0;i<16;i++)
            scanf("%d",&M[i]);
        ans=-1;
        for(int i=0;i<=5;i++){
            if(IDA(i,0))
                break;
        }
        printf("%d\n",ans);
    }
}



HDU 1560 IDA*  http://acm.hdu.edu.cn/showproblem.php?pid=1560

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
int n;
char s[8][6];
int ls[8];
int p[8];
char ss[6]={"ACTG"};

inline int h(){
    int num=0;
    for(int i=0;i<n;i++)
        if(num<ls[i]-p[i])
            num=ls[i]-p[i];
    return num;
}

int ans;
bool IDA(int g){
    int H=h();
    if(H==0) return 1;
    if(g+H>ans) return 0;
    int tem[8];
    for(int i=0;i<n;i++)
        tem[i]=p[i];
    for(int i=0;i<4;i++){
        bool sign=0;
        for(int j=0;j<n;j++)
            if(ss[i]==s[j][p[j]])
                p[j]++,sign=1;
        if(sign){
            if(IDA(g+1)) return 1;
            for(int j=0;j<n;j++)
                p[j]=tem[j];
        }
    }
    return 0;
}
int main(void){
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++) scanf("%s",s[i]),ls[i]=strlen(s[i]);
        ans=0;
        memset(p,0,sizeof(p));
        while(!IDA(0)){
            memset(p,0,sizeof(p));
            ans++;
        }
        printf("%d\n",ans);
    }
}


HDU 1813 IDA* http://acm.hdu.edu.cn/showproblem.php?pid=1813

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 1000
#define maxn 100
char map[10][10];
int h[10][10];
int dis[4][2]={0,1,-1,0,1,0,0,-1};
queue<int> q;
int n;
int d[maxn];
int ans;
struct node{
    int x,y;
}u[maxn];
int lu;
void geth(){
    while(!q.empty()) q.pop();
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if((i==0||j==0||i==n-1||j==n-1)&&map[i][j]=='0'){
                h[i][j]=0;
                q.push(i*n+j);
            }
        }
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        int x=u/n,y=u%n;
        for(int i=0;i<4;i++)
        {
            int nx=x+dis[i][0];
            int ny=y+dis[i][1];
            if(nx<0||ny<0||nx>=n||ny>=n) continue;
            if(map[nx][ny]=='1') continue;
            if(h[nx][ny]>h[x][y]+1){
                h[nx][ny]=h[x][y]+1;
                q.push(nx*n+ny);
            }
        }
    }
}
void getu(){
    lu=0;
    for(int i=1;i<n-1;i++)
        for(int j=1;j<n-1;j++)
            if(map[i][j]=='0')
                u[lu].x=i,u[lu].y=j,lu++;
}
int H(){
    int num=0;
    for(int i=0;i<lu;i++)
        num=max(num,h[u[i].x][u[i].y]);
    return num;
}
bool IDA(int g){
    int hh=H();
    if(hh==0) return 1;
    if(hh+g>ans) return 0;
    node tem[maxn];
    for(int i=0;i<lu;i++)
        tem[i]=u[i];
    for(int i=0;i<4;i++){
        for(int j=0;j<lu;j++){
            int x=u[j].x;
            int y=u[j].y;
            if(h[x][y]==0) continue;
            int nx=x+dis[i][0];
            int ny=y+dis[i][1];
            if(nx<0||ny<0||nx>=n||ny>=n||map[nx][ny]=='1') continue;
            u[j].x=nx;
            u[j].y=ny;
            d[g]=i;
        }
        if(IDA(g+1)) return 1;
        for(int j=0;j<lu;j++)
            u[j]=tem[j];
    }
    return 0;
}
char s[4][8]={{"east"},{"north"},{"south"},{"west"}};
int main(void){
    int cas=0;
    while(scanf("%d",&n)!=EOF){
        if(cas!=0)
            printf("\n");
        cas++;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                h[i][j]=INF;
        for(int i=0;i<n;i++)
            scanf("%s",map[i]);
        if(n<=2) continue;
        geth();
        getu();
        ans=0;
        while(!IDA(0))
            ans++;
        for(int i=0;i<ans;i++){
            printf("%s\n",s[d[i]]);
        }
    }
}


HDU 2918 IDA* http://acm.hdu.edu.cn/showproblem.php?pid=2918

#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
#define INF 999999999
#define maxn 20000
int x[10];
int old[4][4]={
    1,2,5,4,
    2,3,6,5,
    4,5,8,7,
    5,6,9,8
};

int ans=0;
void rcge(int k){
    int tem=x[old[k][0]];
    for(int i=1;i<4;i++)
        x[old[k][i-1]]=x[old[k][i]];
    x[old[k][3]]=tem;
}

void cge(int k){
    int tem=x[old[k][3]];
    for(int i=2;i>=0;i--)
        x[old[k][i+1]]=x[old[k][i]];
    x[old[k][0]]=tem;
}

int h(){
    int num=0;
    for(int i=1;i<=9;i++)
        if(x[i]!=i) num++;
    if(num==0) return 0;
    return num<=3?2:(num-1)/4+1;
}

bool IDA(int g)
{
    int H=h();
    if(H+g>ans) return 0;
    if(H==0) return 1;
    for(int i=0;i<4;i++){
        cge(i);
        if(IDA(g+1)) return 1;
        rcge(i);
        rcge(i);
        if(IDA(g+1)) return 1;
        cge(i);
    }
    return 0;
}

int main(){
    int n;
    int cas=1;
    while(scanf("%1d",&n)!=EOF){
        for(int i=1;i<=9;i++)
            scanf("%1d",&x[i]);
        if(x[1]==0) break;
        ans=0;
        while(ans<=n&&!IDA(0)) ans++;
        if(ans>n) printf("%d. -1\n",cas++);
        else printf("%d. %d\n",cas++,ans);
    }
}


HDU 2918 IDA*  http://acm.hdu.edu.cn/showproblem.php?pid=2918

#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
#define INF 999999999
#define maxn 20000
int old1[3][4]={
    8,9,17,16,
    0,1,3,2,
    6,7,15,14
};
int old2[3][8]={
    7,3,1,10,18,23,21,15,
    11,10,9,8,7,6,5,4,
    2,3,8,16,21,20,13,5
};
int face[6][4]={
    4,5,12,13,     //L
    10,11,18,19,   //B
    20,21,22,23,   //D
    8,9,16,17,     //R
    6,7,14,15,     //F
    0,1,2,3        //U
};
char cf[6];
char map[6][10];
char x[26];
char kind[5]={"XYZ\0"};
void ch(int k){
    int tem=x[old1[k][0]];
    for(int i=1;i<4;i++) x[old1[k][i-1]]=x[old1[k][i]];
    x[old1[k][3]]=tem;
    int tem0=x[old2[k][0]];
    int tem1=x[old2[k][1]];
    for(int i=1;i<4;i++){
        x[old2[k][(i-1)*2]]=x[old2[k][i*2]];
        x[old2[k][(i-1)*2+1]]=x[old2[k][i*2+1]];
    }
    x[old2[k][6]]=tem0;
    x[old2[k][7]]=tem1;
}

void rch(int k){
    char tem=x[old1[k][3]];
    for(int i=2;i>=0;i--) x[old1[k][i+1]]=x[old1[k][i]];
    x[old1[k][0]]=tem;
    char tem0=x[old2[k][6]];
    char tem1=x[old2[k][7]];
    for(int i=2;i>=0;i--){
        x[old2[k][(i+1)*2]]=x[old2[k][i*2]];
        x[old2[k][(i+1)*2+1]]=x[old2[k][i*2+1]];
    }
    x[old2[k][0]]=tem0;
    x[old2[k][1]]=tem1;
}

void get_x_cf(){
    int lx=0;
    for(int i=0;i<6;i++)
        for(int j=0;map[i][j];j++)
            if(map[i][j]!='.')
                x[lx++]=map[i][j];
    x[lx]='\0';
    cf[0]=x[12];cf[1]=x[19];cf[2]=x[22];
}

int h(){
    int num0=0;
    for(int i=0;i<3;i++){
        int tem=0;
        for(int j=0;j<4;j++)
            if(x[face[i][j]]!=cf[i]) tem++;
        num0=max(tem,num0);
    }
    int num1=0;
    for(int i=3;i<6;i++){
        if(num1) break;
        for(int j=1;j<4;j++)
            if(x[face[i][j]]!=x[face[i][j-1]]){
                num1=1; break;
            }
    }
    return max(num0,num1);
}
int ans;
char aans[100];
int laans;
bool IDA(int g,int k)
{
    int H=h();
    if(H+g>ans) return 0;
    if(H==0){ aans[laans++]=kind[k];return 1;}
    for(int i=0;i<3;i++){
        ch(i);
        if(IDA(g+1,i)){aans[laans++]=kind[k];return 1;}
        rch(i);
    }
    return 0;
}

int main(){
    while(1){
        memset(aans,'\0',sizeof(aans));
        laans=0;
        for(int i=0;i<6;i++)
            scanf("%s",map[i]);
        if(map[0][2]=='.') break;
        get_x_cf();
        ans=0;
        while(!IDA(0, 3)) ans++;
        laans--;
        for(int i=0;i<laans/2;i++)
            swap(aans[i],aans[laans-i-1]);
        puts(aans);
    }
}


POJ 2449 K短路 Dijkstra+A* http://poj.org/problem?id=2449

细节 :起点等于终点时 K+1

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
#define maxn 1005
#define maxm 100005
#define INF 1e9
int h[maxn];
int n,m;
struct Edge
{
    int u,v,w;
}e[maxm];
struct Node{
    int u,dis,h;
    Node(){};
    Node(int a,int b,int c=0){u=a;dis=b;h=c;}
    bool friend operator < (Node a,Node b){return a.dis+a.h>b.dis+b.h;}
};
vector<int> G[maxn];
vector<int> T[maxn];
priority_queue<Node> q;


bool mark[maxn];
void Dijkstra(int st,int nd){
    while(!q.empty()) q.pop();
    for(int i=0;i<=n;i++) h[i]=INF;
    memset(mark,0,sizeof(mark));
    h[st]=0;
    q.push(Node(st,h[st]));
    while(!q.empty()){
        Node x=q.top();
        q.pop();
        int u=x.u;
        if(mark[u]) continue;
        mark[u]=1;
        for(int i=0;i<T[u].size();i++){
            int v=e[T[u][i]].u;
            int w=e[T[u][i]].w;
            if(x.dis+w<h[v]){
                h[v]=x.dis+w;
                q.push(Node(v,h[v]));
            }
        }
    }
}


int cnt[maxn];
int Astar(int st,int nd,int k){
    while(!q.empty()) q.pop();
    memset(cnt,0,sizeof(cnt));
    q.push(Node(st,0,h[st]));
    while(!q.empty()){
        Node x=q.top();
        q.pop();
        cnt[x.u]++;
        if(cnt[x.u]>k) continue;
        if(cnt[nd]==k) return x.dis;
        for(int i=0;i<G[x.u].size();i++){
            Edge ee=e[G[x.u][i]];
            if(cnt[ee.v]>=k) continue;
            q.push(Node(ee.v,x.dis+ee.w,h[ee.v]));
        }
    }
    return -1;
}
void clear(){
    for(int i=0;i<=n;i++)
        G[i].clear(),T[i].clear();
}


int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
            G[e[i].u].push_back(i);
            T[e[i].v].push_back(i);
        }
        int st,nd,k;
        scanf("%d%d%d",&st,&nd,&k);
        if(st==nd) k++;
        Dijkstra(nd, st);
        int ans=Astar(st,nd,k);
        printf("%d\n",ans);
        clear();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值