蓝桥杯模拟赛4.D.路径配对[搜索+判重]

 

D. 试题D: 路径配对 17'

描述

JM构造了一个完美三角形,如图所示。分别是每个小三角形的编号,以及每一个三角形的权值。

15850238921032.png编号图15849900676016.png权值图

现在JM想找出两条不相交路径,他们的路径和相等,这样的方案有多少种?

路径:从任意一个格子出发,朝着相邻有公共边的格子所形成的轨迹(一条路径不能经过同一个格子两次)。

路径和:路径上所经过的格子权值之和。

不相交路径:即两条路径没有经过共同的格子。

如果两条路径所经过的格子完全相同,则视为同一条路径。

例如:

路径A:A->C->B->F->G->H->D

路径B:A->C->D->H->G->F->B

路径A和路径B视为同一条路径。

注意:

  • 不存在一条路径,刚好经过I,M,N,O,P,5个格子,因为一条路径中不经过同一个格子两次.
  • (A,B),(B,A)视为同一种方案,例如下图 合法方案一 合法方案二 属于同一种方案。
15849912149790.png合法方案一15849913489406.png合法方案二

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个数字,填写多余的内容将无法得分。

 

  • Python语言选手

print("你的答案")

  • C/C++语言选手

#include <stdio.h>

int main()

{

printf("你的答案");

return 0;

}

  • Java语言选手

public class Main{
public static void main(String[] args){
System.out.println("你的答案");
}
}

输入

 

输出

 

样例

输入


输出


/*
cnblog: shenben

实现思路:
dfs1遍历所有路径path1,dfs2 遍历所有路径,检验 与path1权值相等的path2,
判重:
1、对于path1/path2把路径点从小到大排序
2、 path1,path2组合,用 path1+"&"+path2 ("&"可以是任意分隔符)
具体见函数calcs(...) 
-----    每一种不重复的合法组合,视作一种方案   -----
举个易错的例子:
存在(1)、(2)合法 
(1)ABCEF    IO
(2)ABCFG    IO
但不存在 ABCEF ABCFG这种情况
所以不要轻易尝试从数学上考虑,老老实实搜索~ 
判重的时候老老实实组合判重,不多不少 
*/
#include<bits/stdc++.h>
#define pb emplace_back
#define fi first
#define se second
using namespace std;
#define debug(x) cerr<<#x<<" "<<x<<endl;
#define fop(x) freopen(#x,"r",stdin);
const int N=1005;
int len1,len2,res1,res2,ans,w[N]={0,1,3,2,2,4,2,4,4,7,3,5,6,3,1,5,2};
int tmps[N],path1[N],path2[N];int vis[N];
vector<int>g[N];
map<string,int>sgm;
void work2();
void add(int x,int y){
    g[x].pb(y);g[y].pb(x);
}
string gethash(int n,int *p){
    for(int i=1;i<=n;i++) tmps[i]=p[i];
    sort(tmps+1,tmps+n+1);
    string s="";
    for(int i=1;i<=n;i++) s+=char(tmps[i]+'A'-1);
    return s; 
}
string calcs(string s1,string s2){
    if(s1>s2) swap(s1,s2);
    return s1+"&"+s2;
}
void checknow(){
    if(res1==res2){
        string s1=gethash(len1,path1);
        string s2=gethash(len2,path2);
        string ss=calcs(s1,s2);
        if(!sgm[ss]) sgm[ss]=1,ans++;
    } 
}
void dfs1(int x,int len=1){
    res1+=w[x];
    path1[len1=len]=x;
    work2();
    for(int &i:g[x]){
        if(!vis[i]){
            vis[i]=1; 
            dfs1(i,len+1);
            vis[i]=0;
        }
    }
    res1-=w[x];
}
void dfs2(int x,int len=1){
    res2+=w[x];
    path2[len2=len]=x;
    checknow();
    for(int &i:g[x]){
        if(!vis[i]){
            vis[i]=1; 
            dfs2(i,len+1);
            vis[i]=0;
        }
    }
    res2-=w[x];
}
void work1(){
    for(int i=1;i<=16;i++) if(!vis[i]) vis[i]=1,dfs1(i),vis[i]=0;
}
void work2(){
    for(int i=1;i<=16;i++) if(!vis[i]) vis[i]=1,dfs2(i),vis[i]=0;
}
int main(){
    //1...16分别代表'A'...'P' 
    for(int i=2;i<4;i++) add(i,i+1);
    for(int i=5;i<9;i++) add(i,i+1);
    for(int i=10;i<16;i++) add(i,i+1);
    add(1,3);
    add(2,6);add(4,8);
    add(5,11);add(7,13);add(9,15);
    work1();
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2020-04-20 21:55  神犇(shenben)  阅读(255)  评论(0编辑  收藏  举报