码迷,mamicode.com
首页 > 其他好文 > 详细

ACM 暴力搜索题 题目整理

时间:2014-08-18 21:56:12      阅读:371      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   ar   

UVa 129 Krypton Factor

注意输出格式,比较坑爹。

每次要进行处理去掉容易的串,统计困难串的个数。

bubuko.com,布布扣
#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<string>
#define INF 1000000000LL
#define ll long long
using namespace std;
char str[100];
int cnt,K,L;
bool check(int len)
{
    int l=strlen(str);
    if(l==0||l==1) return false;
    for(int i=1; i<=len/2; ++i)
    {
        bool ok=true;
        for(int j=0; j<i&&ok; ++j)
        {
            if(str[len-1-j]!=str[len-1-i-j])
                ok=false;
        }
        if(ok) return true;
    }
    return false;
}
void dfs(int pos)
{
    if(cnt>=K) return ;
    else
    {
        for(int i=0; i<L; ++i)
        {
            str[pos]=A+i;
            str[pos+1]=0;
            if(!check(pos+1)) cnt++;
            else continue ;
            dfs(pos+1);
            if(cnt>=K) return ;
        }
    }
}
int main()
{
    while(scanf("%d%d",&K,&L)!=EOF)
    {
        if(!K&&!L) break;
        cnt=0;
        dfs(0);
        int L=strlen(str);
        for(int i=0; str[i]; ++i)
        {
            if(i&&i%4==0&&i%64) putchar( );
            putchar(str[i]);
            if((i+1)%64==0) putchar(\n);
        }
        if(L%64) putchar(\n);
        printf("%d\n",L);
    }
    return 0;
}
View Code

 

SPOJ COMCB  1003

注意棋盘方格总数不会超过26。所以可以尝试dfs回溯寻找最优解。

怎么找字典序最小的,这个把棋盘画出来,然后指定一下每次跳的方向的顺序就行。如果第一个跳完全部棋盘的就是最优解。

这里要求输出最优解,每个位置是二维的,可以把它们压缩成一维,开一个数组,下标存第几步,内容存位置,这样就方便储存了。

实际上可行解并不多,可以打表。

 

bubuko.com,布布扣View Code

 

HDU 4848 Wow! Such Conquering!

首先用fylod求最短路,然后搜索。时间复杂度大约是30!。肯定要剪枝。

有两个剪枝,一个是如果当前时刻有星球永远无法到达,则return,另一个是如果到该星球以后的时间花费比当前最优解要小则剪枝。这样就能过了。

bubuko.com,布布扣
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 100000000
using namespace std;
int dist[35][35],tim[35];
int n;
int ans;
bool vis[35];
void dfs(int now,int rest,int all,int sum)
{
    if(all>=ans) return ;
    if(rest==0)
    {
        ans=min(ans,all);
        return ;
    }
    for(int i=1; i<n; ++i)
        if((!vis[i])&&(sum+dist[now][i]>tim[i]))
            return;
    for(int i=1; i<n; ++i)
    {
        if(!vis[i])
        {
            int time=sum+dist[now][i];
            if(time<=tim[i])
            {
                if(ans<=all+rest*time) continue;
                vis[i]=true;
                dfs(i,rest-1,all+time,time);
                vis[i]=false;
            }
        }
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0; i<n; ++i)
            for(int j=0; j<n; ++j)
            {
                scanf("%d",&dist[i][j]);
            }
        for(int k=0; k<n; ++k)
            for(int i=0; i<n; ++i)
                for(int j=0; j<n; ++j)
                    dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
        for(int i=1; i<n; ++i)
        {
            scanf("%d",&tim[i]);
        }
        ans=inf;
        memset(vis,0,sizeof(vis));
        vis[0]=true;
        dfs(0,n-1,0,0);
        if(ans==inf) puts("-1");
        else printf("%d\n",ans);
    }
    return 0;
}
View Code

 

 SGU 125  Shtirlits

给一个矩阵B,每个元素B[i][j]表示A[i][j]上下左右四周有多少个数大于自身。输出一个可能的矩阵A。

由于n<=3,完全可以暴力搜索解决。但是9^9肯定会超时的,考虑剪枝。对于每个A[i][j]枚举可能的元素,当枚举到第二行以上的时候,该元素上面的一个元素四周的元素都已经确定了,可以判断是否满足题意,不满足则剪枝。当枚举到最后一行的时候,还可以判断左边的元素是否满足题意。当所有元素都枚举完毕,要进行一次全体的判断,如果符合就是答案。

之前想到一个剪枝,以为每次枚举A[i][j],可以从0枚举到9-B[i][j]。其实这是不对的,因为比A[i][j]大的元素可能是相同的。

bubuko.com,布布扣
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int B[4][4];
int A[4][4];
int n;
bool judge(int x,int y)
{
    return 0<=x&&x<n&&0<=y&&y<n;
}
const int Move[4][2]= {{-1,0},{0,-1},{1,0},{0,1}};
bool check(int x,int y)
{
    int cnt=0;
    for(int i=0; i<4; ++i)
    {
        int nx=x+Move[i][0],ny=y+Move[i][1];
        if(judge(nx,ny))
        {
            if(A[x][y]<A[nx][ny])
                cnt++;
        }
    }
    return cnt==B[x][y];
}
bool dfs(int cur)
{
    if(cur==n*n)
    {
         for(int i=0;i<n;++i)
            for(int j=0;j<n;++j)
            if(!check(i,j)) return false;
         return true;
    }
    const int x=cur/n,y=cur%n;
    for(int i=0; i<=9; ++i)
    {
        A[x][y]=i;
        if((x>=1&&!check(x-1,y))||(x==n-1&&y>=1&&!check(x,y-1)))
            continue;
        if(dfs(cur+1))
            return true;
    }
    return false;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0; i<n; ++i)
            for(int j=0; j<n; ++j)
                scanf("%d",&B[i][j]);
        if(!dfs(0))
            puts("NO SOLUTION");
        else
        {
            for(int i=0; i<n; ++i)
            {
                for(int j=0; j<n; ++j)
                    if(!j) printf("%d",A[i][j]);
                    else printf(" %d",A[i][j]);
                printf("\n");
            }
        }
    }
    return 0;
}
View Code

 

ACM 暴力搜索题 题目整理,布布扣,bubuko.com

ACM 暴力搜索题 题目整理

标签:style   blog   http   color   os   io   for   ar   

原文地址:http://www.cnblogs.com/kkkwjx/p/3873944.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!