挑战程序设计竞赛 2章习题 poj 2718 Smallest Difference dfs
Description Given a number of distinct decimal digits, you can form one integer by choosing a non-empty subset of these digits and writing them in some order.
The remaining digits can be written down in some order to form a second integer. Unless the resulting integer is 0, the integer may not start with the digit 0. For example, if you are given the digits 0, 1, 2, 4, 6 and 7, you can write the pair of integers 10 and 2467.
Of course, there are many ways to form such pairs of integers: 210 and 764, 204 and 176, etc.
The absolute value of the difference between the integers in the last pair is 28, and it turns out that no other pair formed by the rules above can achieve a smaller difference. Input The first line of input contains the number of cases to follow. For each case, there is one line of input containing at least two but no more than 10 decimal digits.
(The decimal digits are 0, 1, ..., 9.) No digit appears more than once in one line of the input. The digits will appear in increasing order, separated by exactly one blank space. Output For each test case, write on a single line the smallest absolute difference of two integers that can be written from the given digits as described by the rules above. Sample Input 1 0 1 2 4 6 7 Sample Output 28
地址 https://vjudge.net/problem/POJ-2718
题意大概是给出 不重复的0~9的数字 要求组合成两个数字 差值最小
输出最小的差值作为答案
考点是DFS穷举遍历, 给出的数字的所有组合 然后分为长度接近或者长度相同的数字 计算差值
没有使用stl中的库函数 自己编写DFS进行的穷举所有数列组合
注意 如果数字有两位以上,0 不能作为数字开头
数字全排列可以参考这篇题解
LeetCode 046. 全排列 dfs 和 dfs_swap
视频地址 https://www.bilibili.com/video/BV1Pp4y1B7on
代码
#include <iostream> #include <algorithm> #include <vector> #include <algorithm> using namespace std; /* 1 0 1 2 4 6 7 28 */ int totallen; char arr[50]; int n; int ans = 99999999; void calc() { int len = totallen / 2; int a = 0; int b = 0; if (arr[0] == '0' && len > 1) return; if (arr[len] == '0' && (totallen - len) > 1) return; for (int i = 0; i < len; i++) { a += arr[i] - '0'; a = a * 10; } a = a / 10; for (int i = len; i < totallen; i++) { b += arr[i] - '0'; b = b * 10; } b = b / 10; ans = min(ans, abs(b - a)); return; } //产生输入数组的不同组合 进行差值比较 void dfs(int start) { if (start >= totallen) { calc(); return; } for (int i = start ; i < totallen; i++) { swap(arr[start], arr[i]); dfs(start+1); swap(arr[start], arr[i]); } } int solve() { //产生该arr可能的各种组合 然后计算组合差值 dfs(0); return 0; } int main() { char tmp='\0'; scanf("%d",&n); while(tmp != '\n') scanf("%c", &tmp); while (n--) { memset(arr, 0, sizeof arr); totallen = 0; ans = 99999999; while (totallen < 50) { scanf("%c",&tmp); if (tmp != ' '&& tmp != '\r'&& tmp != '\n') { arr[totallen] = tmp; totallen++; } if (tmp == '\n') break; } solve(); printf("%d\n",ans); } return 0; }
按次序交换两位数字 形成新的组合
组合取一半长度组成的数字 ,取剩下的元素组成新的数字 求差.
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> #include <algorithm> #include <set> #include <stdio.h> using namespace std; int arr[11]; int len; int t, n; int ans; int a[5]; int alen; int b[5]; int blen; set<int> vis; int toNum(int c[], int clen) { int sum = 0; //排除0开头的错误组合 但是长度为1 是可以选择0的 if (clen > 1 && c[0] == 0) return 0x3f3f3f3f; for (int i = 0; i < clen; i++) { sum = sum * 10 + c[i]; } return sum; } void Check() { //计算两者之差 int alen = len / 2; blen = 0; for (int i = 0; i < alen; i++) { a[i] = arr[i]; } for (int i = alen; i < len; i++) { b[blen++] = arr[i]; } int an = toNum(a, alen); int bn = toNum(b, blen); //cout << an << " " << bn << endl; ans = min(ans, abs(an - bn)); } void dfs(int curr) { if (curr == len) { //计算两者之差 Check(); return; } for (int i = curr; i < len; i++) { //位置curr和自己和后面的索引交换 也就是该数字变化和不变化我们都需要考虑。 swap(arr[i], arr[curr]); dfs(curr + 1); swap(arr[i], arr[curr]); } } void solve() { ans = 0x3f3f3f3f; //从第一位和后面某位开始交换 并且计算生成的数字之差。 dfs(0); cout << ans << endl; } int main() {//本题的数目比较麻烦 所有接受输入的代码有点多 scanf("%d", &t); char c; while (1) { scanf("%c", &c); if ('\n' == c) { break; } } while (t--) { memset(arr, 0, sizeof arr); ans = 0x3f3f3f3f; vis.clear(); len = 0; for (int i = 0; i <= 100; i++) { scanf("%c", &c); if ('\n' == c) { break; } else if (c >= '0' && c <= '9') { arr[len++] = c - '0'; } } //接受输入后 开始计算 solve(); } return 0; }
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
2018-03-17 基于内存,redis,mysql的高速游戏数据服务器设计架构 ZT