csdn编程竞赛题:A、B两个单词通过一个单词集合Dict的最小路径

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

/*
给了A、B两个单词和一个单词集合Dict,每个的长度都相同。
我们希望通过若干次操作把单词A变成单词B,每次操作可以改变单词中的一个字母,
同时,新产生的单词必须是在给定的单词集合Dict中。求所有行得通步数最少的修改方法。    
举个例子如下: Given:    A = "hit"    B = "cog"    
Dict = ["hot","dot","dog","lot","log"] 
Return  [    ["hit","hot","dot","dog","cog"],    ["hit","hot","lot","log","cog"]  ]     
即把字符串A = "hit"转变成字符串B = "cog",有以下两种可能: 
"hit" -> "hot" ->  "dot" ->  "dog" -> "cog"; 
"hit" ->  "hot" ->  "lot" ->  "log"  ->"cog"。
*/

const int word_len = 3; // 单词固定长度
const int item_count = 7; // 单词项数
const char *words[item_count] ={"hit","hot","dot","dog","lot","log", "cog"};
vector<int> vec;
vector<vector<int>> result_vec; // 保存路径结果
vector<int>::iterator iter; 

//两个单词之间是否相通 
int linked(const char * str1, const char * str2) 
{
 if(str1==str2) 
  return -1; // 完全相同
 int different = 0;
 for(int i=0; i<word_len; ++i){
  if( str1[i] != str2[i]){
   ++different;
  }
 }
 return different==1? 1 : 0; //1 代表只有1个不同字母, 0 代表多于1个不同字母
}

void getpath(int start, int end,vector<int> &vec)
{
 vec.push_back(start); // 加入可能的路径
 for(int i=0; i< item_count; ++i){
  if(linked(words[start], words[i]) == 1 ){   
   if(linked(words[i], words[end]) == 1 ){// 是否target 
    vec.push_back(i);
    vec.push_back(end);
    result_vec.push_back(vec);
    vec.pop_back();
    vec.pop_back();
    break; // 当前是最短路径, 不需要再往下找了
   }
   // 查找是否已经包含当前的单词
     iter = find(vec.begin(), vec.end(), i);
   if(iter == vec.end()){
    int linked_count = 0;
    for(iter=vec.begin();iter<vec.end();++iter){
     if(linked(words[*iter], words[i]) == 1){
      linked_count++;
     }
    }
    if(linked_count==1){ // 列表中只能有1个单词和当前的单词相通,否则就不是最佳路径
     getpath(i, end, vec);
    }
   }
  }
 }
 vec.pop_back(); //当前路径不通, 抛弃
}

void find_path()
{
 const int start = 0;
 const int end = 6;
 getpath(start,end, vec);
 // 输出结果
 cout<<"Return [ ";
 for(vector<vector<int>>::iterator it= result_vec.begin();it!=result_vec.end();++it) {
  cout <<(it == result_vec.begin()?"[":", [");
  for(iter = it->begin(); iter!=it->end(); ++iter){
   cout<<(iter == it->begin()?"\"":",\"")<<words[*iter]<<"\"";
  }
  cout<<"]";
 }
 cout <<" ]"<<endl;
}


在线答题发送失败, 放在这里以便以后备查.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值