D. 试题D: 路径配对 17'
描述
JM构造了一个完美三角形,如图所示。分别是每个小三角形的编号,以及每一个三角形的权值。
编号图权值图现在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)视为同一种方案,例如下图 合法方案一 与 合法方案二 属于同一种方案。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个数字,填写多余的内容将无法得分。
- 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 ",ans); return 0; }