Educational Codeforces Round 104 (Rated for Div. 2) F.Ones(数位dp)

这篇博客介绍了一种动态规划的方法来解决给定一个正整数n,使用1和加减运算找到最少需要多少个1来表示n的问题。通过分析1的后效性和高位对低位的影响,博主提出了从高位到低位的动态规划状态转移方程,并给出了相应的C++代码实现。该算法考虑了可能的借位情况,并优化了1的使用次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

给一个正整数n(1<=n<=1e50),你只能用包含1的数以及加减两种运算去计算这个数,问最少需要多少个1。

例如,24=11+11+1+1,最少需要6个1;而102=111-11+1+1,最少需要7个1。

思路来源

libreOJ群

题解

一个很重要的性质是,注意到111111*6=1111111-111111*4-1,即用6次看上去不如从高位借下来优,

但是有1*6=11-1*5,所以表明每一个长度的串1都最多用不会超过6次

也就是低位的1不会产生进位,即不会对高位产生影响,

前对后有影响,后对前无影响,这启发我们从高到低dp,

dp[i][j][k]表示考虑前i位时,当前造的前缀这个数和原串前缀i位的数相差为j,当前还有k个前缀1在后续发挥作用时的最小需要的1的个数

其实就是需要存下来两个状态,一个是和真正的答案还偏离多少,

另一个是还有多少个1有后效性,记录下来就没有后效性了

考虑到可能要借位,前面补几个0

代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
const int A=200,B=330,INF=0x3f3f3f3f;
void Min(int &x,int y){x=min(x,y);}
int n,dp[55][A*2+5][B*2+5];
//111111*6=1111111-111111*4-1
//1*6=11-1*5
string s;
int main(){
	cin>>s;
	s="0000"+s;
	memset(dp,INF,sizeof dp);
	dp[0][A][B]=0;
	n=s.length();
	for(int i=0;i<n;++i){
		for(int j=-A;j<=A;++j){
			for(int k=-6*i;k<=6*i;++k){
				if(dp[i][j+A][k+B]==INF)continue;
				//dbg1(i),dbg1(j),dbg1(k),dbg2(dp[i][j+A][k+B]);
				for(int l=-6;l<=6;++l){
					int nk=k+l;
					int nj=j*10+nk-(s[i]-'0');
					if(nj<-A || nj>A)continue;
					Min(dp[i+1][nj+A][nk+B],dp[i][j+A][k+B]+(n-i)*abs(l));
				}
			}
		}
	}
	int ans=INF;
	for(int k=-6*n;k<=6*n;++k){
		ans=min(ans,dp[n][A][k+B]);
	}
	printf("%d\n",ans);
	return 0;
} 

 

<think>好的,我现在要帮用户解答关于C语言putchar函数的用法和示例的问题。首先,我得回忆一下自己对putchar函数的了解。putchar是C标准库中的一个函数,用于向标准输出(通常是屏幕)输出一个字符。它属于stdio.h头文件,所以使用时需要包含这个头文件。 接下来,我需要确认用户的需求。用户明确提到了“使用方法”和“示例”,所以我的回答应该包括这两个部分。此外,用户可能还需要知道函数的基本语法、参数、返回值以及注意事项。可能还需要对比其他输出函数,比如printf或者puts,来帮助用户理解putchar的特点。 根据提供的引用内容,用户给出的三个引用都涉及putchar的基本用法和示例代码。例如,引用[1]和[2]都展示了如何用putchar输出一个字符变量,而引用[3]提到了putchar在文件处理中的应用,但具体例子可能不够详细。需要注意的是,用户提供的引用中可能存在重复的信息,比如示例代码几乎相同,所以需要整合这些信息,避免重复。 首先,我应该解释putchar函数的原型,即int putchar(int char),说明参数虽然类型是int,但实际处理的是字符的ASCII码。返回值方面,成功时返回写入的字符,失败返回EOF。这点很重要,可能用户在使用时需要注意错误处理,但常见示例可能忽略返回值检查,所以需要指出。 然后是基本使用方法,比如输出单个字符。这里可以给出示例代码,如用户提供的示例,输出字符'A'。同时,可能需要指出putchar只能输出一个字符,不能直接输出字符串。如果要输出字符串,需要结合循环逐个字符输出,比如遍历字符串中的每个字符并用putchar输出。这样也能展示putchar的实际应用场景。 另外,用户可能想知道putchar和printf的区别。例如,printf功能更强大,可以格式化输出,而putchar更高效,适合单个字符的输出。这可能是一个常见的对比点,应该在回答中提到。 关于示例,除了输出单个字符外,还可以展示输出换行符,比如putchar('\n'),或者结合循环输出一串字符。比如用户提到的遍历字符串的例子,这可以作为一个更复杂的示例,说明如何用putchar实现字符串的输出。 同时,需要注意用户提供的引用中可能存在错误或者需要澄清的地方。例如,引用[3]提到putchar的原型是int putchar(const char * string),这显然不正确,正确的原型应该是int putchar(int char)。这可能是一个引用错误,需要在回答中纠正,避免误导用户。 另外,用户的问题可能涉及到使用putchar时的常见错误,比如传递一个字符串而不是单个字符,或者忘记包含stdio.h头文件,导致编译错误。这些注意事项也应该包含在回答中,帮助用户避免常见问题。 总结一下,我的回答结构应该是: 1. 函数简介:说明putchar的作用和所属头文件。 2. 函数原型:正确写出函数原型,解释参数和返回值。 3. 基本使用方法:输出单个字符的示例,强调参数类型和字符与ASCII码的关系。 4. 进阶应用:如输出字符串、换行符等,结合循环结构。 5. 注意事项:常见错误、返回值处理、与其他函数的对比。 6. 示例代码:给出几个不同的例子,覆盖基本和进阶用法。 在编写示例代码时,要确保语法正确,比如包含stdio.h,使用main函数的结构,以及正确的语法格式。同时,需要指出每个示例的作用和运行结果,让用户清楚代码的效果。 最后,根据系统指令,需要生成相关问题。这些问题应该围绕putchar的扩展应用、与其他函数的比较、错误处理等,帮助用户进一步学习。例如: - putchar和printf的区别是什么? - 如何用putchar输出整数数字? - putchar在文件操作中的应用是怎样的? 需要检查引用是否正确,用户提供的引用中有错误的地方要纠正,比如引用[3]的函数原型错误,应在回答中指出正确的形式,避免混淆。 可能还需要提到putchar通常用于低级输出,或者在需要高效输出单个字符时的场景,比如实现自定义的字符串输出函数,或者在某些嵌入式系统中使用。 总之,要确保回答准确、全面,同时结构清晰,符合用户的需求,并且提供有用的示例和相关问题,促进用户深入学习。</think>### C语言putchar函数的使用方法及示例 #### 1. 函数简介 `putchar` 是C语言标准库函数,用于向标准输出(通常是屏幕)输出**单个字符**,需包含头文件 `stdio.h`。其特点是简单高效,适用于字符级输出。 #### 2. 函数原型 ```c int putchar(int char); ``` - **参数**:`char` 为要输出的字符(以ASCII码形式传递,实际使用时可直接用字符类型)。 - **返回值**:成功时返回写入的字符,失败返回 `EOF`(End Of File)。 #### 3. 基本用法 **示例1:输出单个字符** ```c #include <stdio.h> int main() { char ch = 'A'; putchar(ch); // 输出字符'A' return 0; } ``` **结果**:屏幕显示 `A`。 **示例2:直接输出ASCII码** ```c putchar(65); // 65是'A'的ASCII码,输出结果同上 ``` #### 4. 进阶应用 **输出字符串(需结合循环)** ```c #include <stdio.h> int main() { char str[] = "Hello"; for (int i = 0; str[i] != '\0'; i++) { putchar(str[i]); // 逐个输出字符 } return 0; } ``` **结果**:屏幕显示 `Hello`。 **输出特殊字符** ```c putchar('\n'); // 输出换行符 putchar('\t'); // 输出制表符 ``` #### 5. 注意事项 1. **仅支持单个字符**:若尝试输出字符串(如 `putchar("A")`),会导致编译错误[^3]。 2. **返回值处理**:需检查返回值以确认是否成功写入(例如在文件操作中)。 3. **与 `printf` 对比**:`putchar` 效率更高,但功能单一;`printf` 支持格式化输出。 #### 6. 错误用法示例 ```c putchar("A"); // 错误!参数应为字符类型,而非字符串 ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值