P1957 口算练习题

记录58

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int f(int x){
  if(x==0) return 1;
	int s=0;
	while(x){
		s++;
		x=x/10;		
	}
	return s;
}
int main(){
	string s1="",s2="",s3="";
	int i,n,m,ans=0,cnt=0;
	char op,c;
	cin>>i;
	while(i--){
		ans=0,cnt=0;
		cin>>s1>>s2;
		if(s1[0]>='a'&&s1[0]<='c'){
			cin>>s3;
			n=stoi(s2);
			m=stoi(s3);
			c=s1[0];
		}
		else{
			n=stoi(s1);
			m=stoi(s2);
		} 
		switch (c){
			case 'a':
				ans=n+m;
				op='+';
				break;
			case 'b':
				ans=n-m;
				op='-';
				break;
			case 'c':
				ans=n*m;
				op='*';
				break;
			default:
				break;
		}
		cnt+=f(n)+f(m)+f(ans)+2;
		if(ans<0) cnt++;
		printf("%d%c%d=%d\n",n,op,m,ans);
		cout<<cnt<<endl;
	}
	return 0;
} 

题目传送门https://www.luogu.com.cn/problem/P1957


突破点

若该行为三个数据则第一个数据表示运算类型,a 表示加法运算,b 表示减法运算,c 表示乘法运算,接着的两个数据表示参加运算的运算数。

若该行为两个数据,则表示本题的运算类型与上一题的运算类型相同,而这两个数据为运算数。


思路

  1. 运算符号跟等号是恒定的两个 👉 计算数字的长度
  2. 判断是否跟上一个相同 👉 输入的字符串第一个字符
  3. 进行对应的运算

代码简析

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int f(int x){
  if(x==0) return 1;
	int s=0;
	while(x){
		s++;
		x=x/10;		
	}
	return s;
}
int main(){
	string s1="",s2="",s3="";
	int i,n,m,ans=0,cnt=0;
	char op,c;
	cin>>i;
	while(i--){
		...
	}
	return 0;
} 

int f(int x){...} 👉 计算数字的长度

string s1="",s2="",s3=""; 👉 输入的运算符或者数字

int i(算式数量),n(第一个数字),m(第二个数字),ans=0(运算的答案),cnt=0(总长度);

char op(运算符),c(运算类型);

while(i--){} 👉 输入i行算式

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int f(int x){
  if(x==0) return 1;
	int s=0;
	while(x){
		s++;
		x=x/10;		
	}
	return s;
}
int main(){
	string s1="",s2="",s3="";
	int i,n,m,ans=0,cnt=0;
	char op,c;
	cin>>i;
	while(i--){
		ans=0,cnt=0;
		cin>>s1>>s2;
		if(s1[0]>='a'&&s1[0]<='c'){
			cin>>s3;
			n=stoi(s2);
			m=stoi(s3);
			c=s1[0];
		}
		else{
			n=stoi(s1);
			m=stoi(s2);
		} 
		switch (c){
			case 'a':
				ans=n+m;
				op='+';
				break;
			case 'b':
				ans=n-m;
				op='-';
				break;
			case 'c':
				ans=n*m;
				op='*';
				break;
			default:
				break;
		}
		cnt+=f(n)+f(m)+f(ans)+2;
		if(ans<0) cnt++;
		printf("%d%c%d=%d\n",n,op,m,ans);
		cout<<cnt<<endl;
	}
	return 0;
} 

ans=0,cnt=0; 👉 对每行算式初始化

if(s1[0]>='a'&&s1[0]<='c'){} 👉 判断运算类型在三种运算中,然后保留运算数字跟运算类型

else{} 👉 跟上个式子为同一个运算符

注意 :stoi()函数是将字符串类型转换为整数类型,如果报错,解决办法放在文章的补充部分介绍

switch (c){} 👉 选择操作的情况

cnt+=f(n)+f(m)+f(ans)+2; 👉 累加计算总长度

if(ans<0) cnt++; 👉 如果结果是负数,额外计算负号长度


补充

stoi()函数如果在Dev-C++中无法使用,根本原因是编译器不支持C++11标准(或支持但未开启)。以下是详细分析和解决方案:


1. 根本原因:Dev-C++默认编译器版本过旧

stoi()C++11 引入的标准库函数,而Dev-C++默认搭载的MinGW编译器版本(通常是4.8或更早)不完全支持C++11 ,或默认未开启C++11支持

报错信息

复制代码
error: 'stoi' is not a member of 'std'
error: 'stoi' was not declared in this scope

2. 解决方案(二选一)

方案A:开启C++11支持(推荐)
cpp 复制代码
// Dev-C++ 5.11及以上版本
// 菜单栏:工具 → 编译选项 → 编译器选项卡
// 在"编译器"框中添加:
-std=c++11

// 或代码中添加(不推荐,治标不治本)
#define _GLIBCXX_USE_C99 1
#include <string>
using namespace std;
int main() {
    string s = "123";
    int x = stoi(s);  // 现在可用
}
方案B:改用兼容的替代函数(比赛保命)
cpp 复制代码
// 方式1:stringstream(C++98可用,最推荐)
#include <sstream>
string s = "123";
stringstream ss;
ss << s;
int x;
ss >> x;

// 方式2:atoi()(需转char*)
#include <cstdlib>
string s = "123";
int x = atoi(s.c_str());  // 必须c_str()转换

// 方式3:手动实现(竞赛常用)
int myStoi(string s) {
    int ans = 0, sign = 1, i = 0;
    if (s[0] == '-') { sign = -1; i = 1; }
    for (; i < s.size(); i++) ans = ans * 10 + (s[i] - '0');
    return ans * sign;
}

3. 竞赛建议(CSP-J铁律)

** 绝对不要 在竞赛中使用stoi() **

原因:

  1. 编译环境未知:CSP-J评测机可能用旧版GCC(4.8),默认不开C++11

  2. 编译失败 = 0分stoi()编译错误,题目直接WA

  3. 替代方案成熟stringstreamatoi()100%兼容

推荐竞赛模板(100%安全)
cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

// 万能字符串转数字模板(支持long long)
inline long long strToLL(const string &s) {
    long long ans = 0, sign = 1, i = 0;
    if (s[0] == '-') { sign = -1; i = 1; }
    for (; i < (long long)s.size(); i++) ans = ans * 10 + (s[i] - '0');
    return ans * sign;
}

inline int strToInt(const string &s) {
    return (int)strToLL(s);  // 转int
}

// 使用
string s = "-12345";
int x = strToInt(s);  // x = -12345
ll y = strToLL(s);    // y = -12345LL

4. Dev-C++版本问题详解

Dev-C++版本 默认GCC版本 C++11支持 stoi()可用性
5.11 4.9.2 ✅ 支持(需手动开启) 添加-std=c++11后可用
5.10 4.8.1 ⚠️ 部分支持 可能编译失败
4.9 4.8.0 ❌ 不支持 必须替代
5.15+ 9.2.0 ✅ 支持(默认开启) 可用

建议 :升级Dev-C++到5.15 以上,或改用VS Code + MinGW-w64


5. 一句话总结

stoi()在Dev-C++中不能用是因为编译器不支持C++11;竞赛中坚决不能用stoi(),统一用stringstream或手写转换函数,避免编译失败直接0分。

相关推荐
前端程序猿之路12 小时前
30天大模型学习之Day 2:Prompt 工程基础系统
大数据·人工智能·学习·算法·语言模型·prompt·ai编程
a35354138212 小时前
设计模式-原型模式
开发语言·c++
liulilittle12 小时前
libxdp: No bpffs found at /sys/fs/bpf
linux·运维·服务器·开发语言·c++
星火开发设计12 小时前
堆排序原理与C++实现详解
java·数据结构·c++·学习·算法·排序算法
2501_9418036212 小时前
在柏林智能城市照明场景中构建实时调控与高并发能耗数据分析平台的工程设计实践经验分享
算法
CoderIsArt12 小时前
常用SCSI数据结构的详细注释和用法
数据结构
福楠12 小时前
C++ STL | list
c语言·开发语言·数据结构·c++·算法·list
努力学算法的蒟蒻12 小时前
day55(1.6)——leetcode面试经典150
算法·leetcode·面试
s砚山s12 小时前
代码随想录刷题——二叉树篇(十)
算法
2301_7644413312 小时前
基于HVNS算法和分类装载策略的仓储系统仿真平台
人工智能·算法·分类