搜索的题

1005 生日礼物

#include<algorithm>
#include<cstdio>
#include<iostream>
using namespace std;
int as[10][12],fs[12],sum[12],maxn=1001;
int n,m;
void dfs(int s)
{
    for(int i=0;i<=fs[s];i++)
    {
        for(int k=1;k<=m;k++)
            sum[k]+=as[s][k]*i;
        if(s<n) dfs(s+1);
        else
        {
            int flag=0;
            for(int k=2;k<=m;k++)
                if(sum[k]!=sum[k-1])
                {
                    flag=1;break;
                }
            if(!flag)
                if(sum[1]*m<maxn&&sum[1]>0)
                    maxn=sum[1]*m;
        }
        for(int k=1;k<=m;k++)
            sum[k]-=as[s][k]*i;
    }
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>as[i][j];
    for(int i=1;i<=n;i++)
        cin>>fs[i];
    dfs(1);
    if(maxn<=1000) cout<<maxn;
    else cout<<"alternative!";
    return 0;
}

代码

1225 八数码难题

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
const int hashn = 999997;
int hash[hashn];
struct node{
    int s[3][3];
};

struct node1{
    node point;
    int step;
    int x, y;
};

queue<node1> q;
node dest = {1,2,3,8,0,4,7,6,5};
const int dx[] = {0, 0, 1, -1};
const int dy[] = {-1, 1, 0, 0};

bool operator == (node &x, node &y){
    for(int i = 0; i < 3; i++)
        for(int j = 0; j < 3; j++)
            if(x.s[i][j] != y.s[i][j])    return false;
    return true;
}

void bfs(){
    while(!q.empty()){
        node1 u = q.front(); q.pop();
        for(int i = 0; i < 4; i++){
            int x1 = u.x + dx[i];
            int y1 = u.y + dy[i];
            if(x1 < 0 || x1 >= 3 || y1 < 0 || y1 >= 3)    continue;
            node now = u.point;
            now.s[u.x][u.y] = now.s[x1][y1];
            now.s[x1][y1] = 0;
            if(now == dest){
                cout << u.step + 1 << endl;
                return;
            }
            int n = 0;
            for(int j = 0; j < 3; j++)
                for(int k = 0; k < 3; k++)
                    n = n*10 + now.s[j][k];
            int nn = n % hashn;
            while(hash[nn] != n && nn < hashn){
                if(hash[nn] == -1)    break;
                nn++;
            }
            if(hash[nn] == -1){
                node1 v;
                hash[nn] = n;
                v.point = now;
                v.x = x1, v.y = y1;
                v.step = u.step + 1;
                q.push(v);
            }
        }
    }
}

int main(){
    memset(hash, -1, sizeof(hash));
    char c;
    node st;
    int x0, y0, n = 0;
    for(int i = 0; i < 3; i++)
        for(int j = 0; j < 3; j++){
             cin >> c;
             if(c == ‘0‘){
                 x0 = i; y0 = j;
             }
             st.s[i][j] = c - ‘0‘;
             n = n*10 + st.s[i][j];
        }
    int nn = n % hashn;
    hash[nn] = n;
    node1 st0;
    st0.point = st; st0.step = 0; st0.x = x0; st0.y = y0;
    q.push(st0);
    bfs();
    return 0;
}

代码

1004 四子连棋

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int xx[5] = {0,0,0,1,-1};
int yy[5] = {0,1,-1,0,0};

int map[5][5],minn = 1000;//利用数组代表“黑、白、空” minn代表所求的最小步数
char s;
void Dfs(int x,int y,int num,int b)
{
    int m = 100000,i,j,k;
    if(num >= minn)
        return;
    for(i = 1;i <= 4;i ++)
    {
        if(map[i][1] == map[i][2] && map[i][2] == map[i][3] && map[i][3] == map[i][4] && (map[i][4] == 1 || map[i][4] == 2))//行相同更新
        m = num;
        if(map[1][i] == map[2][i] && map[2][i] == map[3][i] && map[3][i] == map[4][i] && (map[4][i] == 1 || map[4][i] == 2))//列相同更新
        m = num;
    }
    if(map[1][1] == map[2][2] && map[2][2] == map[3][3] && map[3][3] == map[4][4] && (map[4][4]==1 || map[4][4] == 2))//左上到右下相同更新
        m = num;
    if(map[4][1] == map[3][2] && map[3][2] == map[2][3] && map[2][3] == map[1][4] && (map[1][4]==1 || map[1][4] == 2))//右上到左下相同更新
        m = num;
    if(m < minn)//m在上面已经更新为当前接了 这里用m更新minn
    {
        minn = m;
        return;//不用往后搜索了 因为后面不如现在优
    }
    for(i = 1;i <= 4;i ++)
    {
        int tx = x + xx[i];//横坐标更新
        int ty = y + yy[i];//纵坐标更新
        if(tx > 0 && tx <= 4 && ty > 0 && ty <= 4 && map[tx][ty] == b)//边界判断
        {
            map[x][y] = map[tx][ty];
            map[tx][ty] = 0;//走完之后map[tx][ty]变空  map[x][y]变map[tx][ty]
            if(b == 1)
            b = 2;//黑白交替走 上次走黑 下次走白
            else b = 1;
            for(j = 1;j <= 4;j ++)//因为空格又不止一个 所以 找空格
            for(k = 1;k <= 4;k ++)
            if(!map[j][k])//空格的值为0
                Dfs(j,k,num+1,b);
            map[tx][ty] = map[x][y];//回溯
            map[x][y] = 0;
            if(b == 1)  b = 2;
            else    b = 1;
        }
    }
}
int main()
{
    int i,j;
    for(i = 1;i <= 4;i ++)
    for(j = 1;j <= 4;j ++)
    {
        cin >> s;
        if(s == ‘W‘) map[i][j] = 1;//白棋
        if(s == ‘B‘) map[i][j] = 2;//黑棋
    }
    for(i = 1;i <= 4;i ++)
    for(j = 1;j <= 4;j ++)
    if(!map[i][j])//空格
    {
        Dfs(i,j,0,1);//先走白棋
        Dfs(i,j,0,2);//先走黑棋
    }
    cout<<minn<<endl;
    return 0;
}

代码

时间: 2024-10-13 23:27:11

搜索的题的相关文章

POJ 1979 Red and Black 深度优先搜索上手题

Red and Black Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21738   Accepted: 11656 Description There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a

华为题 搜索水题 DFS

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <string> 6 #include <iterator> 7 #include <algorithm> 8 #include <cstdlib> 9 #include <deque> 10 #include &l

HDU 1142 A Walk Through the Forest (Dijkstra + 记忆化搜索 好题)

A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6350    Accepted Submission(s): 2332 Problem Description Jimmy experiences a lot of stress at work these days, especial

BZOJ 1415 NOI2005 聪聪和可可 期望DP+记忆化搜索 BZOJ200题达成&amp;&amp;NOI2005全AC达成

题目大意:给定一个无向图,聪聪在起点,可可在终点,每个时刻聪聪会沿最短路走向可可两步(如果有多条最短路走编号最小的点),然后可可会等概率向周围走或不动,求平均多少个时刻后聪聪和可可相遇 今天早上起床发现194了然后就各种刷--当我发现199的时候我决定把第200题交给05年NOI仅剩的一道题--结果尼玛调了能有一个小时--我居然没看到编号最小这个限制0.0 首先我们知道,由于聪聪走两步而可可走一步,所以聪聪一定能在有限的时刻追上可可,而且两人的距离随着时间进行单调递减 于是我们记忆化搜索 首先用

搜索基础题

1.http://acm.hdu.edu.cn/showproblem.php?pid=1312 题意:在一个仅有红黑格子组成的矩形中,一个人只能走上下左右相邻黑色格子,问从起点开始共能走多少个格子? ’#‘:红色格子 ’.': 黑色格子: ’@‘:起点 BFS 和 DFS 都可以遍历所有走的点,每次走过一点时,计数++即可: 2.http://acm.hdu.edu.cn/showproblem.php?pid=1728 由题可知,在限制转弯数量的前提下 能够从一点走到另一个点即可:BFS 和

搜索刷题记录

我好菜啊!连暴搜都不会! 注意边界退出! 特开此帖,记录搜索学习之路!(逃) 1.全排列 2.八皇后 3.数的划分 由于此题有同一划分方法算一个的限制,我们为了避免搜多,可以使搜出的结果满足单调不降性,那么就要在dfs时传一个pre参数. 由于要使划分后数之和为n,记录当前搜的总值sum. 由于有划分k个的限制,记录当前搜出了几个. 小总结,dfs函数的参数由其限制条件得出. 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9368382.htm

hdu4845 状态压缩搜索水题

这道题简单来说是和胜利大逃亡续类似的题  只不过这道题没有给你明确的地图 只给了你点之间的关系          唯一的坑点在于一个点可能有多把钥匙 #include<stdio.h> #include<string.h> #include<iostream> #include<queue> using namespace std; struct node { int x,y,step,state; }a,b; int mark[16][16][3030];

POJ 3249 Test for Job (记忆化搜索 好题)

Test for Job Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9512   Accepted: 2178 Description Mr.Dog was fired by his company. In order to support his family, he must find a new job as soon as possible. Nowadays, It's hard to have a job

搜索好题UVA1601

题目 分析:如果以当前3个小写字母的位置为状态,则问题转化为图上的最短路问题.但是如果每次都判断小写字母的下一步是否合法,那就是说每次移动都需要判断5^3,肯定会超时.可以把所有可以移动的格子找出来建立一张图,就是把障碍物给删除,统计每个可以空格或者有鬼的格子可以移动到哪些格子,这样在判断的时候就节省了许多时间.然后bfs找最短路.注意读入的时候要多读入一个换行符,因为scanf的缓冲区用完以后,必须要读入一个字符才能才能结束读入,另外就是建图,过程,这个题的建图我给满分. 1 #include

UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题

很少用bfs进行最短路搜索,实际BFS有时候挺方便得,省去了建图以及复杂度也降低了O(N*M): UVA 11624 写的比较挫 #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; struct node{ int ft; int sta; }flo[1010][1010]; int vis[1010][1010]; st