当前位置: 首页 > news >正文

【NOIP提高组】虫食算

【NOIP提高组】虫食算

      • C语言
      • C++


💐The Begin💐点点关注,收藏不迷路💐

所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子:

43#9865#045
+8468#6633
= 44445506678
其中#号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5。
现在,我们对问题做两个限制:

首先,我们只考虑加法的虫食算。这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0。
其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同的数字用不同的字母表示。如果这个算式是N进制的,我们就取英文字母表午的前N个大写字母来表示这个算式中的0到N-1这N个不同的数字:但是这N个字母并不一定顺序地代表0到N-1)。输入数据保证N个字母分别至少出现一次。
BADC
+CRDA
= DCCC

上面的算式是一个4进制的算式。很显然,我们只要让ABCD分别代表0123,便可以让这个式子成立了。你的任务是,对于给定的N进制加法算式,求出N个不同的字母分别代表的数字,使得该加法算式成立,输入数据保证有且仅有一组解。

输入
输入包含4行。第一行有一个正整数N(N<=26),后面的3行每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这3个字符串左右两端都没有空格,从高位到低位,并且恰好有N位。

输出

输出包含一行。在这一行中,应当包含唯一的那组解。解是这样表示的:输出N个数字,分别表示A,B,C……所代表的数字,相邻的两个数字用一个空格隔开,不能有多余的空格。

样例输入

5
ABCED
BDACE
EBBAA

样例输出

1 0 3 4 2

提示

【数据规模】
对于30%的数据,保证有N<=10;
对于50%的数据,保证有N<=15;
对于全部的数据,保证有N<=26。

C语言

#include <stdio.h>
#include <string.h>// 最大可能的字符数,可根据实际情况调整
#define MAX_CHARS 30  int numDigits;  // 存储进制数N,简称numDigits
char addends[4][MAX_CHARS];  // 存储算式的三个数(两个加数与和),简称addends数组
int usedDigits[MAX_CHARS];  // 标记数字是否已被使用,简称usedDigits数组
int digitMapping[MAX_CHARS];  // 存储字母到数字的映射,简称digitMapping数组
int solutionFound;  // 标记是否已找到解,简称solutionFound// 将字符转换为对应的索引(A对应0,B对应1,以此类推)
int charToIndex(char c) {return c - 'A';
}// 递归搜索可能的字母到数字的映射,以找到满足算式的解
void searchMapping(int row, int col, int carry) {int i;// 如果已经找到解,直接返回if (solutionFound == 1) {return;}// 如果已经处理完所有列(从高位到低位)if (col == -1) {// 如果进位为0,说明找到了满足算式的解if (carry == 0) {for (i = 0; i < numDigits; i++) {printf("%d ", digitMapping[i]);}solutionFound = 1;}return;}// 检查当前列的各位数字是否满足加法规则(考虑进位)for (i = col; i >= 0; i--) {int digit1 = digitMapping[charToIndex(addends[1][i])];int digit2 = digitMapping[charToIndex(addends[2][i])];int digit3 = digitMapping[charToIndex(addends[3][i])];if (digit1 == -1 || digit2 == -1 || digit3 == -1) {continue;}if ((digit1 + digit2) % numDigits!= digit3 && (digit1 + digit2 + 1) % numDigits!= digit3) {return;}}// 如果当前位置的字母还没有映射到数字if (digitMapping[charToIndex(addends[row][col])] == -1) {for (i = numDigits - 1; i >= 0; i--) {if (!usedDigits[i]) {// 如果不是处理和的那一行if (row!= 3) {digitMapping[charToIndex(addends[row][col])] = i;usedDigits[i] = 1;searchMapping(row + 1, col, carry);digitMapping[charToIndex(addends[row][col])] = -1;usedDigits[i] = 0;} else {int sum = digitMapping[charToIndex(addends[1][col])] + digitMapping[charToIndex(addends[2][col])] + carry;if (sum % numDigits!= i) {continue;}usedDigits[i] = 1;digitMapping[charToIndex(addends[row][col])] = i;searchMapping(1, col - 1, sum / numDigits);usedDigits[i] = 0;digitMapping[charToIndex(addends[row][col])] = -1;}}}} else {// 如果当前位置的字母已经有映射if (row!= 3) {searchMapping(row + 1, col, carry);} else {int sum = digitMapping[charToIndex(addends[1][col])] + digitMapping[charToIndex(addends[2][col])] + carry;if (sum % numDigits!= digitMapping[charToIndex(addends[3][col])]) {return;}searchMapping(1, col - 1, sum / numDigits);}}
}int main() {// 读取进制数Nscanf("%d", &numDigits);// 读取算式的三个数scanf("%s%s%s", addends[1], addends[2], addends[3]);// 初始化数字映射数组为 -1,表示未映射memset(digitMapping, -1, sizeof(int) * numDigits);// 初始化是否找到解的标记为0solutionFound = 0;// 开始搜索满足算式的字母到数字的映射searchMapping(1, numDigits - 1, 0);return 0;
}

C++

#include <iostream>
#include <string>
#include <cstring>// 最大可能的字符数,可根据实际情况调整
const int MAX_CHARS = 30;  int numDigits;  // 存储进制数N,简称numDigits
std::string addends[4];  // 存储算式的三个数(两个加数与和),简称addends数组
int usedDigits[MAX_CHARS];  // 标记数字是否已被使用,简称usedDigits数组
int digitMapping[MAX_CHARS];  // 存储字母到数字的映射,简称digitMapping数组
bool solutionFound;  // 标记是否已找到解,简称solutionFound// 将字符转换为对应的索引(A对应0,B对应1,以此类推)
int charToIndex(char c) {return c - 'A';
}// 递归搜索可能的字母到数字的映射,以找到满足算式的解
void searchMapping(int row, int col, int carry) {int i;// 如果已经找到解,直接返回if (solutionFound) {return;}// 如果已经处理完所有列(从高位到低位)if (col == -1) {// 如果进位为0,说明找到了满足算式的解if (carry == 0) {for (i = 0; i < numDigits; i++) {std::cout << digitMapping[i] << " ";}solutionFound = true;}return;}// 检查当前列的各位数字是否满足加法规则(考虑进位)for (i = col; i >= 0; i--) {int digit1 = digitMapping[charToIndex(addends[1][i])];int digit2 = digitMapping[charToIndex(addends[2][i])];int digit3 = digitMapping[charToIndex(addends[3][i])];if (digit1 == -1 || digit2 == -1 || digit3 == -1) {continue;}if ((digit1 + digit2) % numDigits!= digit3 && (digit1 + digit2 + 1) % numDigits!= digit3) {return;}}// 如果当前位置的字母还没有映射到数字if (digitMapping[charToIndex(addends[row][col])] == -1) {for (i = numDigits - 1; i >= 0; i--) {if (!usedDigits[i]) {// 如果不是处理和的那一行if (row!= 3) {digitMapping[charToIndex(addends[row][col])] = i;usedDigits[i] = 1;searchMapping(row + 1, col, carry);digitMapping[charToIndex(addends[row][col])] = -1;usedDigits[i] = 0;} else {int sum = digitMapping[charToIndex(addends[1][col])] + digitMapping[charToIndex(addends[2][col])] + carry;if (sum % numDigits!= i) {continue;}usedDigits[i] = 1;digitMapping[charToIndex(addends[row][col])] = i;searchMapping(1, col - 1, sum / numDigits);usedDigits[i] = 0;digitMapping[charToIndex(addends[row][col])] = -1;}}}} else {// 如果当前位置的字母已经有映射if (row!= 3) {searchMapping(row + 1, col, carry);} else {int sum = digitMapping[charToIndex(addends[1][col])] + digitMapping[charToIndex(addends[2][col])] + carry;if (sum % numDigits!= digitMapping[charToIndex(addends[3][col])]) {return;}searchMapping(1, col - 1, sum / numDigits);}}
}int main() {// 读取进制数Nstd::cin >> numDigits;// 读取算式的三个数for (int i = 1; i <= 3; i++) {std::cin >> addends[i];}// 初始化数字映射数组为 -1,表示未映射std::memset(digitMapping, -1, sizeof(int) * numDigits);// 初始化是否找到解的标记为falsesolutionFound = false;// 开始搜索满足算式的字母到数字的映射searchMapping(1, numDigits - 1, 0);return 0;
}

在这里插入图片描述


💐The End💐点点关注,收藏不迷路💐
http://www.lryc.cn/news/476796.html

相关文章:

  • 软件测试面试题个人总结
  • HTML 语法规范——代码注释、缩进与格式、标签与属性、字符编码等
  • 【Wi-Fi】WiFi中QAM及16-QAM、64-QAM、512-QAM、1024-QAM、2048-QAM、4096-QAM整理
  • 红黑树的平衡之舞:数据结构中的优雅艺术
  • angular实现list列表和翻页效果
  • 闯关leetcode——3285. Find Indices of Stable Mountains
  • 算法【Java】—— 动态规划之斐波那契数列模型
  • idea连接docker并构建镜像
  • 百度如何打造AI原生研发新范式?
  • RedisTemplate类中的常用方法粗解(简单明了,预计5分钟看完)
  • 鸿蒙ArkTS中的布局容器组件(Column、Row、Flex、 Stack、Grid)
  • 显存占用 显存测试
  • 快速入门CSS
  • AcWing 1073 树的中心 树形dp (详解)
  • modelscope下载Qwen2.5 72B 模型方法
  • 重学SpringBoot3-整合 Elasticsearch 8.x (二)使用Repository
  • 为什么说模拟电路的难点就在开通过程和关断过程?难在什么地方?
  • CubeIDE BUG-project‘hello‘has no explict encoding set hello
  • 在线PDF转图片网站
  • ps和top的区别
  • 自动驾驶上市潮中,会诞生下一个“英伟达”吗?
  • CSS 计数器:深入解析与高级应用
  • 【真题笔记】15年系统架构设计师要点总结
  • 斗破C++编程入门系列之三十九:多态性:纯虚函数和抽象类(四星斗师)
  • 目前美国的互联网环境
  • 从最小作用量原理推导牛顿三大定律
  • 【系统集成项目管理工程师教程】第4章 信息系统架构
  • docker下迁移elasticsearch的问题与解决方案
  • 占地1.1万平,2亿投资的智能仓储系统:高架库、AGV、码垛机器人……
  • 一个小程序如何对接多个收款账户?