news 2026/4/16 9:05:09

UVa 11166 Power Signs

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 11166 Power Signs

题目描述

给定一个正整数n nn,它的二进制表示为不含前导零的二进制字符串。我们需要将n nn表示为带符号的二进制表示(signed binary representation \texttt{signed binary representation}signed binary representation),即:

n = ∑ i = 0 k a i × 2 i n = \sum_{i=0}^{k} a_i \times 2^in=i=0kai×2i

其中a i ∈ { − 1 , 0 , 1 } a_i \in \{-1, 0, 1\}ai{1,0,1}

在二进制表示中,每一位a i a_iai只能是0 001 11,因此表示是唯一的。但是在带符号的二进制表示中,每一位可以是− 1 -110 001 11,因此表示不唯一。题目要求我们找到一种带符号的二进制表示,使得其中非零数字(即+ 1 +1+1− 1 -11)的个数最少。如果存在多种最优解,则输出其中字典序最小的一个(按照ASCII \texttt{ASCII}ASCII码顺序比较,其中字符的顺序为'+' < '-' < '0')。

输入包含多个测试用例(最多25 2525个),每个测试用例一行,是一个正整数n < 2 50000 n < 2^{50000}n<250000的二进制表示(不含前导零)。输入以n = 0 n = 0n=0结束,该行不需处理。

对于每个测试用例,输出一行,给出满足条件的带符号二进制表示,用字符'+'表示+ 1 +1+1'-'表示− 1 -11'0'表示0 00,且不含前导零。

题目分析

本题的关键在于理解如何通过带符号的二进制表示来减少非零数字的个数。观察普通的二进制表示,连续的1 11串可以通过进位和借位的方式,转换为更少的非零数字。

例如,二进制数7 77的普通表示是111 111111(即4 + 2 + 1 4+2+14+2+1),其中有3 33个非零数字。但我们可以将其表示为100 − 100-100(即8 − 1 8-181),这样只有2 22个非零数字(+ 1 +1+1− 1 -11)。更一般地,连续的k kk1 11可以表示为:

11 … 1 ⏟ k 个 = 2 k − 1 = 2 k − 2 0 \underbrace{1 1 \dots 1}_{k \text{个}} = 2^k - 1 = 2^k - 2^0k111=2k1=2k20

即一个+ 1 +1+1在高位,k − 1 k-1k10 00在中间,一个− 1 -11在最低位。这样就将k kk个非零数字减少到了2 22个。

然而,这还不是最优的。因为当我们进行这样的转换时,会产生一个进位(即将连续1 11串前面的0 00变为1 11)。这个进位可能与更高位的1 11形成新的、更长的连续1 11串,从而可以进一步优化,减少更多的非零数字。

解题思路

基于以上分析,我们可以设计一个贪心算法,从二进制表示的最低位向最高位扫描,处理连续的1 11串。

算法步骤

  1. 初始化:在二进制字符串前添加一个字符'0'作为哨兵,用于处理可能的最高位进位。

  2. 从低位向高位扫描

    • 对于每个位置i ii(从最低位到最高位),如果当前字符是'1',则向前(向高位方向)寻找连续'1'的起始位置j jj(即s [ j ] = ′ 0 ′ s[j] = '0's[j]=0s [ j + 1.. i ] s[j+1..i]s[j+1..i]都是'1')。
    • 计算连续1 11的长度l e n = i − j len = i - jlen=ij
    • 如果l e n ≥ 2 len \ge 2len2,则进行转换:
      • s [ i ] s[i]s[i]改为'-'(表示− 1 -11)。
      • s [ j + 1.. i − 1 ] s[j+1..i-1]s[j+1..i1]改为'0'
      • s [ j ] s[j]s[j]改为'1'(进位)。
      • 注意:这里进位设为'1'而不是'+',因为它可能与更高位的'1'构成更长的连续1 11串,从而在后续扫描中被进一步优化。
    • 特殊情况:如果l e n = 2 len = 2len=2j = 0 j = 0j=0(即连续两个1 11在最高位),则直接将这两个位置设为'+',不进行转换(因为转换后最高位会变成'-',可能不是字典序最小)。
    • 如果l e n = 1 len = 1len=1(单个1 11),则直接将该位置设为'+'
  3. 处理最高位进位:扫描结束后,如果哨兵位s [ 0 ] s[0]s[0]变成了'1',则将其改为'+'

  4. 输出结果:如果s [ 0 ] = ′ 0 ′ s[0] = '0's[0]=0,则从s [ 1 ] s[1]s[1]开始输出;否则从s [ 0 ] s[0]s[0]开始输出。这样可以确保没有前导零。

算法正确性说明

该算法是贪心的,从最低位开始,每次遇到连续长度≥ 2 \ge 221 11串就进行转换。这样做的正确性基于以下观察:

  • 最优子结构:一个数的最优带符号二进制表示,其最低位的决策不会影响更高位的最优性(因为转换只产生向高位的进位,不影响已经处理过的低位)。
  • 贪心选择性质:对于连续的k kk1 11,立即进行转换(变为2 k − 1 2^k - 12k1)总是比保持原样更优或至少不差(当k ≥ 3 k \ge 3k3时严格更优,k = 2 k = 2k=2时需要特殊处理字典序)。
  • 字典序最小:由于我们从低位向高位处理,且在高位尽量保持'+'(而不是'-'),最终得到的表示在非零数字最少的前提下是字典序最小的。

时间复杂度

扫描整个字符串一次,每次处理连续1 11串时可能会修改多个字符,但每个字符最多被修改一次(从'1'改为'0''-'),因此总时间复杂度为O ( n ) O(n)O(n),其中n nn是二进制字符串的长度。由于n ≤ 50000 n \le 50000n50000,算法完全可行。

空间复杂度

只需要存储输入字符串和一些辅助变量,因此空间复杂度为O ( n ) O(n)O(n)

代码实现

// Power Signs// UVa ID: 11166// Verdict: Accepted// Submission Date: 2025-12-20// UVa Run Time: 0.000s//// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constintMAXN=50010;intmain(){chars[MAXN];while(scanf("%s",s+1)==1&&s[1]!='0'){s[0]='0';intn=strlen(s+1);// 从低位向高位扫描(i从n到1)for(inti=n;i>0;i--){if(s[i]=='1'){intj=i-1;// 向前寻找连续1的起始位置while(s[j]=='1')j--;// 检查连续1的长度// 连续1的长度≥2if(i-j>=2){// 特殊情况:连续2个1且在最高位(j==0)if(i-j==2&&j==0)s[i]=s[i-1]='+';else{// 一般情况:转换连续1// 最后一个1变成-1s[i]='-';// 中间的1变成0for(intk=i-1;k>j;k--)s[k]='0';// 进位(前面的0变成1),不变为+,因为有可能与前面的1构成更长的连续1串,// 从而可以得到非0数字更少的表示,从而可能会更优s[j]='1';}}elses[i]='+';// 单个1,直接变成+}}// 处理可能的最高位进位if(s[0]=='1')s[0]='+';// 输出结果if(s[0]=='0')printf("%s\n",s+1);elseprintf("%s\n",s);}return0;}

示例分析

样例输入

10000 1111 10111 0

样例输出

+0000 +000- ++00-

解释

  1. 10000 1000010000(二进制16 1616):

    • 没有连续1 11,直接转换为+0000
  2. 1111 11111111(二进制15 1515):

    • 从低位扫描,连续4 441 11,转换为1000 − 1000-1000,即+000-
  3. 10111 1011110111(二进制23 2323):

    • 首先处理低三位111 111111,转换为100 − 100-100,同时进位使前面变为1 11,得到1100 − 1100-1100
    • 然后处理新的连续两个1 11(在第二位和第三位),但由于它们在最高位且长度为2 22,不转换,直接设为++,最终得到++00-

总结

本题是一道典型的贪心算法题目,关键在于发现通过进位可以将连续的1 11串转换为更少的非零数字,并且这种转换可以连锁进行,从而得到全局最优解。算法的时间复杂度和空间复杂度都是线性的,适合处理大规模的输入数据。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/10 14:40:23

阳极智造演进:从实验室手工到工业4.0的范式革命

引言:一个被忽视的“配角”如何成为制造升级的先锋 2018年,深圳一家小型电池材料实验室里,研究员张薇正小心翼翼地调整电解槽的电流密度。她手中的实验记录本已经泛黄,上面密密麻麻记录着三千多次阳极氧化实验参数——温度误差不超过0.5C,时间精度到秒,但批次一致性始终…

作者头像 李华
网站建设 2026/4/13 19:44:39

数据质量不用人盯死:聊聊“规则 + 阈值 + 自愈”怎么玩才靠谱?

数据质量不用人盯死&#xff1a;聊聊“规则 阈值 自愈”怎么玩才靠谱&#xff1f; 兄弟们&#xff0c;做大数据的要是没被“数据质量”折磨过&#xff0c;我都怀疑你是不是在玩票。线上业务天天变、源头数据花式造、表字段随时加减&#xff0c;今天你多一列&#xff0c;明天我…

作者头像 李华
网站建设 2026/4/15 18:25:33

从降重到改写:6个AI论文网站实测,输出结果自然无痕

开头总结工具对比&#xff08;技能4&#xff09; &#xfffd;&#xfffd; 为帮助学生们快速选出最适合的AI论文工具&#xff0c;我从处理速度、降重效果和核心优势三个维度&#xff0c;对比了6款热门网站&#xff0c;数据基于实际使用案例&#xff1a;工具名称处理速度降重幅…

作者头像 李华
网站建设 2026/4/14 15:12:06

9 个降AI率工具推荐,自考人速看!

9 个降AI率工具推荐&#xff0c;自考人速看&#xff01; AI降重工具&#xff1a;自考论文的智能助手 随着人工智能技术的不断发展&#xff0c;越来越多的学术研究开始借助AI工具完成初稿撰写。然而&#xff0c;对于自考学生而言&#xff0c;AI生成的内容往往存在明显的“AI痕迹…

作者头像 李华
网站建设 2026/4/13 21:09:11

30+零基础转AI:一份高效学习闭环指南

三十多岁想转行AI&#xff0c;没有编程基础&#xff0c;听起来像是不可能完成的任务&#xff1f;但你可能不知道&#xff0c;如今企业最缺的不是写代码的工程师&#xff0c;而是懂业务、会用AI工具解决实际问题的人。你的行业经验&#xff0c;恰恰是你转型的最大资本。第一步&a…

作者头像 李华