蓝桥杯-搜索暴力

1、六角填数

运用stl 中的函数next_permutation(a,a+n)
题意:
7:六角填数
如图【1.png】所示六角形中,填入1~12的数字。

使得每条直线上的数字之和都相同。
图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?

请通过浏览器提交答案,不要填写多余的内容。

答案 10

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int a[12]={1,2,3,4,5,6,7,8,9,10,11,12};
bool fun()
{
    if(a[0]+a[2]+a[5]+a[6]==26)
    {
            if(a[6]+a[7]+a[8]+a[10]==26)
    {
            if(a[0]+a[3]+a[9]+a[10]==26)
    {
            if(a[1]+a[2]+a[3]+a[4]==26)
    {
            if(a[1]+a[5]+a[7]+a[11]==26)
    {
            if(a[4]+a[9]+a[8]+a[11]==26)
    {
        return true;
    }
    }
    }
    }
    }
    }
    return false;
}
int  main()
{
//  a[12]={1,2,3,4,5,6,7,8,9,10,11,12};
    do{
        if(a[0]==1&&a[1]==8&&a[11]==3)
        {
            if(fun())
            {
                cout<<a[5]<<endl;
                break;
            }
        }
    }while(next_permutation(a,a+12));
return 0;
}

2、方格填数

运用全排列,不过要注意条件不要写错了。
答案 1580

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int a[10]={0,1,2,3,4,5,6,7,8,9};
bool fun()
{
    if(abs(a[0]-a[1])==1||abs(a[0]-a[4])==1||abs(a[0]-a[5])==1||abs(a[0]-a[3])==1)
        return false;
    if(abs(a[4]-a[1])==1||abs(a[1]-a[5])==1||abs(a[1]-a[2])==1||abs(a[1]-a[6])==1)
    return false;
    if(abs(a[2]-a[6])==1||abs(a[2]-a[5])==1)
        return false;
    if(abs(a[3]-a[7])==1||abs(a[3]-a[4])==1||abs(a[3]-a[8])==1)
        return false;
    if(abs(a[4]-a[7])==1||abs(a[4]-a[8])==1||abs(a[4]-a[9])==1||abs(a[4]-a[5])==1)
        return false;
    if(abs(a[5]-a[8])==1||abs(a[5]-a[9])==1||abs(a[6]-a[5])==1)
        return false;
    if(abs(a[6]-a[9])==1)
        return false;
    if(abs(a[7]-a[8])==1||abs(a[8]-a[9])==1)
        return false;
        return true;
}
int  main()
{
    int ans=0;
//  a[12]={1,2,3,4,5,6,7,8,9,10};
    do{
        if(fun())
        {
            ans++;
         } 
    }while(next_permutation(a,a+10));
    cout<<ans;
return 0;
}

3、减邮票

正确答案是116
给一个错误的解法吧

错误答案为:222
错误原因,排列出C 12 5 的组合后,判断相连出了问题,错误的判断是,只要每一个有一个相连即可,其实并不是,全部都有相连 可能存在两个连通块。啦啦啦,纸上觉来终觉浅觉,绝知此事要躬行。老师讲的就是这种方法,我不敲一下,真的以为是对的。放个错解,以示教训吧。解是错的,但是运用组合数来找解的思路还是棒棒哒,一下把解的范围缩小了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct node{
    int x;
    int y;
}; 
int i,j,k,m,l;
node num[13];
bool fun()
{
    if((abs(num[i].x-num[j].x)+abs(num[i].y-num[j].y))==1||(abs(num[i].x-num[k].x)+abs(num[i].y-num[k].y))==1||(abs(num[i].x-num[m].x)+abs(num[i].y-num[m].y))==1||(abs(num[i].x-num[l].x)+abs(num[i].y-num[l].y))==1)
    {
            if((abs(num[i].x-num[j].x)+abs(num[i].y-num[j].y))==1||(abs(num[j].x-num[k].x)+abs(num[j].y-num[k].y))==1||(abs(num[j].x-num[m].x)+abs(num[j].y-num[m].y))==1||(abs(num[j].x-num[l].x)+abs(num[j].y-num[l].y))==1)
    {
            if((abs(num[m].x-num[j].x)+abs(num[m].y-num[j].y))==1||(abs(num[m].x-num[k].x)+abs(num[m].y-num[k].y))==1||(abs(num[i].x-num[m].x)+abs(num[i].y-num[m].y))==1||(abs(num[m].x-num[l].x)+abs(num[m].y-num[l].y))==1)
    {
            if((abs(num[k].x-num[j].x)+abs(num[k].y-num[j].y))==1||(abs(num[i].x-num[k].x)+abs(num[i].y-num[k].y))==1||(abs(num[k].x-num[m].x)+abs(num[k].y-num[m].y))==1||(abs(num[k].x-num[l].x)+abs(num[k].y-num[l].y))==1)
    {
                if((abs(num[l].x-num[j].x)+abs(num[l].y-num[j].y))==1||(abs(num[i].x-num[l].x)+abs(num[i].y-num[l].y))==1||(abs(num[l].x-num[m].x)+abs(num[l].y-num[m].y))==1||(abs(num[k].x-num[l].x)+abs(num[k].y-num[l].y))==1)
    {
        cout<<i<<" "<<j<<" "<<m<<" "<<k<<" "<<l<<endl;
        return true;
    }
    }
    }
    }
    }
    return false;
}
int  main()
{
num[1].x=1;
num[1].y=1;
num[2].x=1;
num[2].y=2;
num[3].y=3;
num[3].x=1;
num[4].y=4;
num[4].x=1;
num[5].y=1;
num[5].x=2;
num[6].y=2;
num[6].x=2;
num[7].y=3;
num[7].x=2;
num[8].y=4;
num[8].x=2;
num[9].y=1;
num[9].x=3;
num[10].y=2;
num[10].x=3;
num[11].y=3;
num[11].x=3;
num[12].y=4;
num[12].x=3;
int ans=0;
for(i=1;i<9;i++)
{
    for(j=i+1;j<10;j++)
    {
        for(m=j+1;m<11;m++)
        {
            for(k=m+1;k<12;k++)
            {
                for(l=k+1;l<13;l++)
                {
                    if(fun())
                    {
                        ans++;
                    }
                }
            }
        }
     } 
}
cout<<ans;
return 0;
}

再分享一个错解吧:哈哈,又搞错了
3x4的矩阵中一笔画完的 5个连续的图案一共有多少种

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std; 
int i,j;
int mapp[3][4];
int ans=0;
void dfs(int a,int b,int n)// x,y,几步 
{
    if(n==5)
    {
        ans++;
    }
    if(a+1<3)
    {
        dfs(a+1,b,n+1);
    }
    if(b+1<4)
    {
        dfs(a,b+1,n+1);
    }
}
int  main()
{
for(i=0;i<3;i++)
{
    for(j=0;j<4;j++)
    {
        dfs(i,j,1);
    } 
}
cout<<ans;
return 0;
}

正解:运用深搜,判断连通块
终于正确了,参考了别人的方法,为了避免 一行的最后一个和下一行的第一个在搜索的时候判断连续,把图做了一下处理
【1,2,3,4 ,5,6,7,8, 9, 10,11,12】
【1,2,3,4, 6,7,8,9, 11,12,13,14】
用 -5 +5 表示上下 -1 +1 表示左右,比用0 1 矩阵存储彼此的相邻关系简单许多
博客地址
http://blog.csdn.net/u014552756/article/details/50946197

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int ans=0;
int a[5];
int visited[5];
int num[12]={1,2,3,4,6,7,8,9,11,12,13,14};
int d[4]={-1,1,5,-5}; 
int i,j,k,l,m; 
void dfs(int n)//判断这五个数是不是一个连通块 
{
    for(int i=0;i<4;i++)// 
    {
        int t=a[n]+d[i];
        if(t>14||t<1||t==5||t==10)
        continue;
        for(int j=0;j<5;j++)
        {
            if(visited[j]!=1&&a[j]==t)
            {
                visited[j]=1;
                dfs(j);
            }
        }
    }
}
int  main()
{
for(i=0;i<8;i++)
{
    for(j=i+1;j<9;j++)
    {
        for(k=j+1;k<10;k++)
        {
            for(l=k+1;l<11;l++)
            {
                for(m=l+1;m<12;m++)
                {
                    a[0]=num[i];
                    a[1]=num[j];
                    a[2]=num[k];
                    a[3]=num[l];
                    a[4]=num[m];
                    memset(visited,0,sizeof(visited));
                    visited[0]=1;
                    dfs(0);
                    int f=1;
                    for(int i=0;i<5;i++)
                    {
                        if(visited[i]==0)
                        {
                            f=0;
                        }
                        
                    }
                    if(f)
                    ans++;
                }
            }
        }
     } 
}
cout<<ans;
return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容