您的位置:首页 > 其它

动态规划法之移位译码问题

2015-10-31 23:21 239 查看
前言

  同学找我看看一段不到90行的代码,我从下午2点多收到代码,但是直到6点多才完全看懂。可能因为之前没有看题目就直接看代码,所以直接上手就比较痛苦,花的时间也就比较长了。(自我安慰中%>_<%)

题目描述

  题目是一道ACM题,当时看的时候只有15%的通过率,所以也属于比较难的题目了。

  题目的意思大概意思是:移位密码是一种将消息中的每个字符都转换为其他的字符,按照相应的规律。如果有整数K=3,那么字符串 “we will meet at midnight” 将加密为 “zhzloophhwdwplgqljkw”,也就是向后移三位,按照这样的规律。

  先输入一定数量的单词作为字典,然后输入一段表示密文的字符串。根据字符串来解析得到单词,得到的单词都在开始输入的字典里面,结果输出根据密文字符串得到的最少单词。

  具体的要求大家可以去查看,这里我就不在赘述了。《题目链接

源码参考

# include <iostream>
# include <set>
# include <map>
# include <vector>
# include <list>
# include <cstring>
# include <string>
# include <cstdlib>
using namespace std ;
const int MAX = 1e9 ;
string t ;
int cnt , len ;
string ss [ 100000 ] ;
map < string , int > mmap ;
vector < int > vec ;
int stmin  ; //表示单词数最少的一种情况
int  k  ;
int ansk ;//表示密码采用的K值
void DP ( ){
int llist [ 300 ] = { 0 } ;
int num [ 300 ] = { 0 } ;
int dp [ 300 ] = { 0 } ;
memset ( dp , -1 , sizeof ( dp ) ) ;
dp [ 0 ] = 0 ;
for ( int i = 1 ; i <= len ; i ++ ) {
int minn = MAX , pos = -1 ;
map < string , int > :: iterator tmp ;
for ( int j = 0 ; j < i ; j ++ ) {
if ( j == i - 1 ) {
if ( llist [ i - 1 ] == i - 2 )     break ;
}
if ( dp [ j ] != -1 && dp [ j ] + 1 < minn ) {
string s ;
for ( int h = j ; h < i ; h ++ )
s += t [ h ] ;
map < string , int > :: iterator it = mmap . find ( s ) ;
if ( it != mmap . end ( ) ) {
minn = dp [ j ] + 1 ;
pos = j ;
tmp = it ;
}
}
}
if ( minn != MAX ) {
dp [ i ] = minn ;
num [ i ] = tmp -> second ;
llist [ i ] = pos ;
}
}
if ( dp [ len ] != -1 && dp [ len ] < stmin && len > dp [ len ] * 2 ) {
stmin = dp [ len ] ;
ansk = k ;
vec . clear ( ) ;
for ( int i = len ; i ; i = llist [ i ] ) {
vec . push_back ( num [ i ] ) ;
}
}
}

int main ( )
{
cin . sync_with_stdio ( false ) ;
while ( getline ( cin , t ) , t [ 0 ] ) {
mmap [ t ] = cnt ;
ss [ cnt ++ ] = t ;
}   //输入单词
while ( getline ( cin , t ) , t [ 0 ] != '0' ) {
stmin = MAX ;
len = t . size ( ) ;
for ( k = 0 ; k < 26 ; k ++ ) {
DP ( ) ;
for ( int i = 0 ; i < len ; i ++ ) {
t [ i ] = ( t [ i ] -'a' + 25 ) % 26 + 'a' ;
}   //讲K值从0到25循环判断
}
if ( stmin == MAX )     cout << "NO SOLUTIONS" << endl ;
else {
cout << "k=" << ansk << ':' ;
for ( int i = vec . size ( ) - 1 ; i >= 0 ; i -- ) {
cout << ' ' << ss [ vec [ i ] ] ;   //输出结果
}
cout << endl ;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: