题目大意:
给你n个数字,将这n个数字分为两部分,使其差值最小;
解题思路:
由于n的上限为10,因此全排列函数还是有点用处的,只不过注意一句话:
Unless the resulting integer is 0, the integer may not start with the digit 0.
哇。这个是说如果你这个数不是0,那么这个数就不能以0开头,也就是:
if ((!ac[0] || !ac[num/2]) && num>2) continue;
这句话的存在意义。好比1 1 0 ;
错误的排列就是01, 1结果是0
而正确的则是10, 1 结果是9;
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 1010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(x,y) memset(x,y,sizeof(x))
#define rep(i,n) for(int i=0;i<(n);i++)
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
#define pii pair<int,int>
//#define mp make_pair
#define FI first
#define SE second
#define IT iterator
#define PB push_back
#define Times 10
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int ,int > P;
const double eps = 1e-10;
const double pi = acos(-1.0);
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ll INF = (ll)1e18+300;
const int maxd = 50000 + 5;
int ac[15];
int num;
int solve() {
sort(ac, ac + num);
int ans = inf;
do {
// for (int i = 0; i < num; i++) {
// cout << ac[i] << " ";
// }cout << endl;
int res = 0;
int cns = 0;
int cnt = 1;
if ((!ac[0] || !ac[num/2]) && num>2) continue;
//for (int i = 0; i < num - 1; i++) {
for (int j = num/2 - 1; j >= 0; j--) {
res += cnt * ac[j];
cnt *= 10;
}
cnt = 1;
for (int j = num - 1; j >= num/2; j --) {
cns += cnt * ac[j];
cnt *= 10;
}
//cout << res << " " << cns << endl;
ans = min(ans, abs(res - cns));
//cnt = 1;
//res = cns = 0;
//}
}while(next_permutation(ac, ac + num));
return ans;
}
int main() {
int t;
cin >> t;
getchar();
while(t --) {
num = 0;
while(1) {
char c = getchar();
//cout << c << endl;
if(c >= '0' && c <= '9') {
ac[num ++] = c -'0';
}
else if(c == ' ') {
continue;
}
else if(c == '\n') {
break;
}
}
// for (int i = 0; i < num; i++) {
// cout << ac[i] << endl;
// }
cout << solve() << endl;
}
}
本文探讨了一个经典的算法问题——如何将一组数字分成两部分,使得这两部分的数值之差最小。通过全排列的方法,并考虑了特定的限制条件,如数位不能以0开头等,最终实现了有效的解决方案。

531

被折叠的 条评论
为什么被折叠?



