POJ 1248 Safecracker

这是一篇关于POJ 1248编程题目的解析,主要涉及如何破解具有特定条件的组合密码。文章介绍了问题背景,即保险箱上的铭文由数字和互不相同的大写字母组成,要求找到满足特定数学方程的字母组合。解题思路可能涉及到枚举算法,寻找字典序最大的排列。内容中还提及了一些与密码学和编码相关的词汇和技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

        一组合密码箱上有一段铭文,由一个数字和5到15个互不相同的大写字母组成(包括5和15),打开密码箱的密码有其中5个字母组成(当然是互不相同的,且是按照字典序最大排列的),破解密码满足方程v - w^2 + x^3 - y^4 + z^5 = target,v、w、x、y、z为铭文中的5个不同字母所代表的的值(值按照顺序取字母表中的序号,A=1、B=2.....),target为铭文中的数字(不小于12,000,000),编程求该密码串(测例有任意多个)。

题目链接

注释代码:

/*
 * Problem ID : POJ 1248 Safecracker
 * Author     : Lirx.t.Una
 * Language   : C
 * Run Time   : 157 ms
 * Run Memory : 196 KB
*/

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

//maximum length of quotation,铭文的最大长度为15,再多保存一个'\0'
#define	MAXLEN		16
//to digit,将相应的英文大写字母转化为字母表中的序号
#define	tod(c)	( (c) - 'A' + 1 )

//做降序比较
int
fcmp(const void *a, const void *b) {
	
	return *(char *)b - *(char *)a;
}

int
main() {
	
	char	quo[MAXLEN];//quotation,铭文
	char	dig[MAXLEN];//digits,铭文中字母所对应的序号,由于不超过26,所以用char保存
	int		tar;//target,方程右边的值
	
	char	i;
	char	len;//length,铭文的长度
	
	char	v, w, x, y, z;//表示铭文中的5个字符在quo数组中的位置
	
	while ( scanf("%d %s", &tar, quo), tar ) {
		
		len	= strlen(quo);
		qsort(quo, len, sizeof(char), &fcmp);//对铭文做降序排列以获得最大字典序结果
		
		for ( i = 0; i < len; i++ )
			dig[i] = tod( quo[i] );//获得铭文中大写字母响应的序号值
		
		//枚举搜索
		//结果中各字母互不相同
		for ( v = 0; v < len; v++ )	
		  for ( w = 0; w < len; w++ )
		    if ( w != v )
		      for ( x = 0; x < len; x++ )
		        if ( x != v && x != w )
			  	  for ( y = 0; y < len; y++ )
			        if ( y != v && y != w && y != x )
			          for ( z = 0; z < len; z++ )
				        if ( z != v && z != w && z != x && z != y )
				          //满足题给方程,说明找到解,打印结果
				          if ( tar == dig[v]           -
				                      pow( dig[w], 2 ) +
					                  pow( dig[x], 3 ) -
				                      pow( dig[y], 4 ) +
					                  pow( dig[z], 5)
	      			          ) {
												
						      printf("%c%c%c%c%c\n", quo[v], quo[w], quo[x], quo[y], quo[z]); 
		                      goto lop;//由于铭文降序排列过,因此第一个解必定是字典序最大解,可直接进入下一个测例
				          }

		printf("no solution\n");//全部枚举完无解
											
lop:	continue;
	}
	
	return 0;
}

无注释代码:

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

#define	MAXLEN		16
#define	tod(c)	( (c) - 'A' + 1 )

int
fcmp(const void *a, const void *b) {
	
	return *(char *)b - *(char *)a;
}

int
main() {
	
	char	quo[MAXLEN];
	char	dig[MAXLEN];
	int		tar;
	
	char	i;
	char	len;
	
	char	v, w, x, y, z;
	
	while ( scanf("%d %s", &tar, quo), tar ) {
		
		len	= strlen(quo);
		qsort(quo, len, sizeof(char), &fcmp);
		
		for ( i = 0; i < len; i++ )
			dig[i] = tod( quo[i] );
		
		for ( v = 0; v < len; v++ )	
		  for ( w = 0; w < len; w++ )
		    if ( w != v )
		      for ( x = 0; x < len; x++ )
		        if ( x != v && x != w )
			  	  for ( y = 0; y < len; y++ )
			        if ( y != v && y != w && y != x )
			          for ( z = 0; z < len; z++ )
				        if ( z != v && z != w && z != x && z != y )
				          if ( tar == dig[v]           -
				                      pow( dig[w], 2 ) +
					                  pow( dig[x], 3 ) -
				                      pow( dig[y], 4 ) +
					                  pow( dig[z], 5)
	      			          ) {
												
						      printf("%c%c%c%c%c\n", quo[v], quo[w], quo[x], quo[y], quo[z]); 
		                      goto lop;
				          }

		printf("no solution\n");
											
lop:	continue;
	}
	
	return 0;
}

单词解释:

Klein:克莱恩,人名

Brumbaugh:布伦博,人名

safe:n, 保险箱

combination lock:n, 组合密码锁

engrave:vt, 雕刻

quotation:n, 引用,铭文

numeric:adj, 数值的,数字的

ordinal:adj, 顺序的,依次的

alphabet:n, 字母表

lexicographic/lexicographical:按字典序的

i.e.:that is to say/in other words, 也就是说

encode:vt, 编码

take months of effort to do:花上月的时间做....

combination:n, 组合密码

depolyment:n, 部署(用于军事和计算机)

do sth in preparation for:做某事为...做准备

field depolyment:n, 场部署

methodology:n, 方法论(学)

departmental:adj, 部门的,分科的

regulation:n, 规则,规章/条例

consist of:vt, 由...组成

distinct:adj, 有区别的,独特的

signal:vt, 标志着

break ties with:断绝与...的联系(原文中的意思为各行以答案隔开)

order:n, 顺序

exact:adj, 准确的,精确的

format:n, 格式

uppercase:n, 大写字母

equation:n, 方程式

safecracker:n, 破解保险箱的窃贼

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值