#P4233. 第3题-新奇运算
-
ID: 3308
Tried: 2
Accepted: 1
Difficulty: 5
所属公司 :
阿里
时间 :2025年10月17日-菜鸟
-
算法标签>字符串
第3题-新奇运算
题解
- 映射与表达式:小写字母 a∼z 映射 0∼25;数字字符 1,2,3,4 分别表示 +、−、×、÷(下取整)。表达式形如:L op R,其中 L,R 各含 [1,4]个字母。
- 转换规则:字母按顺序转换为对应数字并拼接为十进制串,例如 kj→109→109。
- 运算:计算 left 与 right 的运算结果;若为 4 则做整除 left/right;若 right=0 且为除法,返回 −1;最终结果若为负,返回其绝对值 ∣res∣。
- 复杂度:转换与计算整体 O(n),其中 n≤9。
C++
#include <bits/stdc++.h>
using namespace std;
static long long lettersToNum(const string &s) {
string num;
num.reserve(s.size() * 2);
for (char c : s) {
int v = c - 'a'; // 仅处理小写字母
num += to_string(v); // 按位拼接
}
return num.empty() ? 0LL : stoll(num);
}
static long long solveOne(string s) {
// 去除首尾空白
auto ltrim = [](string &x){ x.erase(x.begin(), find_if(x.begin(), x.end(), [](unsigned char ch){ return !isspace(ch); })); };
auto rtrim = [](string &x){ x.erase(find_if(x.rbegin(), x.rend(), [](unsigned char ch){ return !isspace(ch); }).base(), x.end()); };
ltrim(s); rtrim(s);
// 去掉可能的首尾引号
if (s.size() >= 2 && s.front() == '"' && s.back() == '"') {
s = s.substr(1, s.size() - 2);
}
// 移除内部所有空白
string t; t.reserve(s.size());
for (unsigned char ch : s) if (!isspace(ch)) t.push_back(ch);
s.swap(t);
// 找运算符
int opPos = -1;
for (int i = 0; i < (int)s.size(); ++i) {
if (s[i] >= '1' && s[i] <= '4') { opPos = i; break; }
}
string L = s.substr(0, opPos);
string R = s.substr(opPos + 1);
char op = s[opPos];
long long left = lettersToNum(L);
long long right = lettersToNum(R);
long long res = 0;
if (op == '1') res = left + right; // 加
else if (op == '2') res = left - right; // 减
else if (op == '3') res = left * right; // 乘
else { // 除(下取整)
if (right == 0) return -1;
res = left / right;
}
return res < 0 ? -res : res; // 数学岛没有负数
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string line;
while (getline(cin, line)) {
// 跳过纯空行
bool allspace = true;
for (unsigned char ch : line) if (!isspace(ch)) { allspace = false; break; }
if (allspace) continue;
cout << solveOne(line) << '\n';
}
return 0;
}
Python
import sys
def letters_to_num(s: str) -> int:
# 将字母串转为数字拼接
return int("".join(str(ord(c) - ord('a')) for c in s)) if s else 0
def solve_one(s: str) -> int:
s = s.strip()
if len(s) >= 2 and s[0] == '"' and s[-1] == '"':
s = s[1:-1]
s = "".join(ch for ch in s if not ch.isspace())
op_pos = next(i for i, ch in enumerate(s) if ch in "1234")
left, right = s[:op_pos], s[op_pos+1:]
op = s[op_pos]
L = letters_to_num(left)
R = letters_to_num(right)
if op == '1':
res = L + R
elif op == '2':
res = L - R
elif op == '3':
res = L * R
else:
if R == 0:
return -1
res = L // R
return -res if res < 0 else res
def main():
for line in sys.stdin:
if line.strip() == "":
continue
print(solve_one(line))
if __name__ == "__main__":
main()
Java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
static long lettersToNum(String s) {
StringBuilder sb = new StringBuilder(s.length() * 2);
for (int i = 0; i < s.length(); i++) {
int v = s.charAt(i) - 'a';
sb.append(v);
}
String numStr = sb.length() == 0 ? "0" : sb.toString();
return Long.parseLong(numStr);
}
static long solveOne(String s) {
s = s.trim();
if (s.length() >= 2 && s.charAt(0) == '"' && s.charAt(s.length() - 1) == '"') {
s = s.substring(1, s.length() - 2 + 1);
}
// 去掉所有空白字符
StringBuilder clean = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (!Character.isWhitespace(s.charAt(i))) clean.append(s.charAt(i));
}
s = clean.toString();
int opPos = -1;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch >= '1' && ch <= '4') { opPos = i; break; }
}
String Ls = s.substring(0, opPos);
String Rs = s.substring(opPos + 1);
char op = s.charAt(opPos);
long L = lettersToNum(Ls);
long R = lettersToNum(Rs);
long res;
if (op == '1') res = L + R;
else if (op == '2') res = L - R;
else if (op == '3') res = L * R;
else {
if (R == 0) return -1;
res = L / R;
}
return res < 0 ? -res : res;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = br.readLine()) != null) {
if (line.trim().isEmpty()) continue;
System.out.println(solveOne(line));
}
}
}
题目内容
在神奇的数学岛上,岛民们使用一种独特的符号系统来进行日常计算。在这个世界中,仅存在小写字母 a ~ z ,以及数字字符 1,2,3,4 ,但是它们所代表的含义与现实世界有所不同。
小写字母依次对应数字 0 ~ 25,例如:小写字母 a 代表数字 0 ,小写字母 x 代表数字 23 。
数字字符 1,2,3,4 分别对应着运算符 +、−、×、÷,其中,数字字符 4 所对应的除法运算指的是向下取整除法,即在数学岛上没有小数的概念。
现在,以字符串形式给出一个合法的表达式,所谓合法的表达式,是指这个字符串中一定包含且仅包含一个数字字符(必定是 1,2,3,4 中的一个),同时,在数字字符的两侧,各包含至少一个、至多四个小写字母。例如:
-
表达式 c3d 表示计算 2×3,结果为 6 ;
-
表达式 kj4k 表示计算 109÷10,因为除法对应下取整,所以结果为 10 ;
需要注意,运算符左侧的字母部分按照字母从左到右的顺序,依次转换成对应的数字,再拼接成一个整体,同理,右侧的字母也进行相同的转换。如果最终的计算结果为负数,请返回其绝对值,因为数学岛上不存在负数;
如果在除法中遇到除数为 0 的情况,请返回 −1 以表示表达式有误(该值仅用于表示错误,除此之外不能返回其他负数值)。
补充说明
函数的第一个参数输入一个字符串 formula 代表公式。保证公式合法,即其一定包含一个运算符 (1,2,3,4) 以及运算符左右的字母部分、字母部分的长度满足 1≦len≦4 。字母部分转化得到的数字可能包含前导零,但是当你以现实世界的格式输出答案时,不应该不含前导零。
注:该题为核心模式,不需要自己处理输入输出,代码中的类名、方法名、参数名已经指定,请勿修改,直接书写函数返回方法规定的值即可。
样例1
输入
"a1aaz"
输出
25
说明
0+25=25
样例2
输入
"z4aaaa"
输出
-1
说明
除数为 0,返回 −1 代表公式有误。
样例3
输入
"j2k"
输出
1
说明
9−10=−1,但是需要取其绝对值,所以答案为 1 。