UVa 843 - Crypt Kicker

203 篇文章 0 订阅
120 篇文章 0 订阅

題目:有一些單詞都成的字典,還有一些加密過的單詞組成的句子(除字母只有空格和換行);

            求出一種可行的解碼方案(字母鍵間構成雙射),沒有解全都輸出*。

分析:搜索、回溯、dfs。對應每個句子中的單詞在字典里搜索對應的匹配項。

            利用回溯法搜索,每次在整個字典中尋找匹配項,如果矛盾則返回;

            矛盾:對應字母映射不同,或被映射的字母已經被別的字母映射到;

說明:有是好久沒做題了:-(。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char dict_word[1001][20];
int  dict_word_length[1001];
char line_word[81][20];
int  line_word_length[81];
char maps[128];

int search(int index, int line_size, int dict_size)
{
	if (index >= line_size) {
		return 1;
	}
	char save[128];
	for (int c = 0; c <= 'z'; ++ c) {
		save[c] = maps[c];
	}
	for (int i = 0; i < dict_size; ++ i) {
		if (line_word_length[index] == dict_word_length[i]) {
			int flag = 1;
			for (int j = 0; j < line_word_length[index]; ++ j) {
				if (!maps[line_word[index][j]] && !maps[dict_word[i][j]-'a']) {
					maps[line_word[index][j]] = dict_word[i][j];
					maps[dict_word[i][j]-'a'] = 1;
				}else if (maps[line_word[index][j]] == dict_word[i][j]) {
					continue;
				}else {
					flag = 0;
					break;
				}
			}
			if (flag && search(index+1, line_size, dict_size)) {
				return 1;
			}
			for (int c = 0; c <= 'z'; ++ c) {
				maps[c] = save[c];
			}
		}
	}
	return 0;
}

int main()
{
	int  n;
	char lines[81];
	scanf("%d",&n);
	for (int i = 0; i < n; ++ i) {
		scanf("%s",dict_word[i]);
		dict_word_length[i] = strlen(dict_word[i]);
	}
	
	getchar();
	while (gets(lines)) {
		memset(maps, 0, sizeof(maps));
		int count = 0, word_index = 0;
		for (int i = 0; lines[i]; ++ i) {
			if (lines[i] >= 'a' && lines[i] <= 'z') {
				line_word[word_index][count ++] = lines[i];
			}else {
				line_word[word_index][count] = 0;
				if (count > 0) {
					line_word_length[word_index] = count;
					word_index ++;
					count = 0;
				}
			}
		}
		if (count > 0) {
			line_word_length[word_index] = count;
			word_index ++;
		}
		
		int flag = search(0, word_index, n);
		for (int i = 0; lines[i]; ++ i) {
			if (lines[i] >= 'a' && lines[i] <= 'z') {
				if (flag) {
					printf("%c",maps[lines[i]]);
				}else {
					printf("*");
				}
			}else {
				printf(" ");
			}
		}
		puts("");
	}
		
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值