1 条题解

  • 0
    @ 2025-4-7 20:52:57

    题意分析:

    题目要求将若干个互不相同的数字分成两个非空集合,每个集合的数字按照某个顺序排列后构成一个整数。构造的整数不能以 0 开头(除非该整数本身为 0)。目标是使两个整数之间的绝对差值最小。

    解题思路:

    1、排序与预处理:

    将输入的数字读入后,存放到一个结构体数组中,并按数字大小排序。这样可以方便后续构造两个整数时,从较小或较大的数字中选择合适的数字。 对于只有两个数字的情况,直接返回两者之差即可。

    2、处理奇偶个数:

    如果数字个数为奇数,需要先为其中一个整数预先选定一个首位数字(且该数字不能是 0),这样两个整数的位数才能相差不超过 1。

    3、枚举初始分配:

    利用循环分别枚举将哪一个数字作为第一个整数的起始数字,以及哪一个数字作为第二个整数的起始数字。

    4、贪心思想:

    在固定初始数字之后,剩下的数字按照一定的贪心策略分配:

    对于第一个整数,从剩余未选数字中依次选取较小的数字填入(保证数字整体较小)。

    对于第二个整数,则从剩余未选数字中依次选取较大的数字填入(保证数字整体较大)。

    这种分配方法有助于平衡两个整数,使得它们之间的差值尽可能小。

    5、计算差值:

    将构造出的两个字符串转换为整数后,计算它们的绝对差值。记录所有枚举情况中得到的最小差值作为答案。

    本题代码

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    using namespace std;
    struct NUM {
    	int v, u;
    	bool operator <(const NUM &x) const {
    		return v < x.v;
    	}
    };
    
    int getdigit(char ch) {
    	if (ch >= '0' && ch <= '9')
    		return ch - '0';
    	return -1;
    }
    
    int mabs(int x) {
    	return x < 0 ? -x : x;
    }
    
    int solve() {
    	char cmd[100], n1[10], n2[10];
    	vector<NUM> nl;
    	NUM tmp;
    	int i, j, p1, p2, ans = 10000000, pp1, pp2;
    	tmp.u = 0;
    
    	gets(cmd);
    	for (i = 0; cmd[i]; i++) {
    		int x = getdigit(cmd[i]);
    		if (x != -1) {
    			tmp.v = x;
    			nl.push_back(tmp);
    		}
    
    	}
    	sort(nl.begin(), nl.end());
    	if (nl.size() == 2) {
    		return nl[1].v - nl[0].v;
    	}
    	p1 = p2 = 0;
    	if (nl.size() % 2) {
    		if (nl[0].v)
    			n1[p1++] = '0' + nl[0].v, nl[0].u = 1;
    		else
    			n1[p1++] = '0' + nl[1].v, nl[1].u = 1;
    	}
    	for (i = 0; i < (int) nl.size(); i++) {
    		if (nl[i].u || nl[i].v == 0 && p1 == 0)
    			continue;
    		nl[i].u = 1;
    		n1[p1++] = '0' + nl[i].v;
    		for (j = 0; j < (int) nl.size(); j++) {
    			if (nl[j].u || nl[j].v == 0 && p2 == 0)
    				continue;
    			nl[j].u = 1, n2[p2++] = '0' + nl[j].v;
    			pp1 = p1, pp2 = p2;
    			{
    				int k, l = 0, r = nl.size() - 1;
    				for (k = 0; k < nl.size() / 2 - 1; k++) {
    					while (nl[l].u)
    						l++;
    					n1[p1++] = '0' + nl[l++].v;
    					while (nl[r].u)
    						r--;
    					n2[p2++] = '0' + nl[r--].v;
    				}
    				n1[p1] = 0, n2[p2] = 0;
    				int aa, bb;
    				sscanf(n1, "%d", &aa);
    				sscanf(n2, "%d", &bb);
    				if (mabs(aa - bb) < ans)
    					ans = mabs(aa - bb);
    			}
    			p1 = pp1, p2 = pp2;
    			nl[j].u = 0, p2--;
    		}
    		nl[i].u = 0, p1--;
    	}
    
    	return ans;
    }
    int main() {
    	int T;
    	scanf("%d\n", &T);
    	while (T--)
    		printf("%d\n", solve());
    	return 0;
    }
    
    • 1

    信息

    ID
    1718
    时间
    1000ms
    内存
    64MiB
    难度
    10
    标签
    递交数
    6
    已通过
    1
    上传者