原题链接:点我跳转
此题思维难度不大,考察选手对于细节的把控。
本题分为四种情况:
-
整数
-
浮点数
-
分数
-
百分数
看似情况很多,实则需要做的操作是一样的。都是 反转 + 去掉前导0 + 可能的要去掉中间的0 + 可能的要去掉后缀0
反转
使用双指针,交换 s[i]
与 s[j]
的值即可。其中,
1
≤
i
<
j
≤
N
1\leq i< j\leq N
1≤i<j≤N。
去掉前导 0
换种思路,去掉前导 0 0 0 也可以从第一个不为 0 0 0 的地方开始输出。
去掉中间的 0
这里使用一种暴力的方法,就是把中间的 0 换成空格,最后不输出空格即可。
去掉后缀 0
从后向前遍历,找到第一个不为零的地址,把它的下一个值标记为结束符。
这样,就大致梳理好了思路,即可快乐地写代码了。
写完题解才发现这种方法挺麻烦的。
不要问我为什么不用 string
,写 char
数组写习惯了。
#include <iostream>
#include <cstring>
const int N = 109;
int st;
char s[N];
void swap(char &a, char &b) { char t = a; a = b; b = t; }
void reverse(char *s, int st, int ed) {
int i = st, j = ed;
while (i < j) {
swap(s[i], s[j]);
i++, j--;
}
} // 反转
int find_st(char *s, int st, int ed) {
for (int i = st; i <= ed; i++)
if (s[i] != '0')
return i;
return 0;
}
void erase_ed(char *s) {
int i = strlen(s) - 1;
while (s[i--] == '0');
s[i+2] = '\0';
}
void erase_md(char *s, int st) {
int i = st;
while (s[i] == '0') s[i++] = ' ';
}
int main() {
scanf("%s", s);
int len = strlen(s);
if (strchr(s, '%') - s >= 0) {
reverse(s, 0, len-2);
st = find_st(s, 0, len-2);
} else if (strchr(s, '.') - s >= 0) {
int add = strchr(s, '.') - s;
reverse(s, 0, add-1);
st = find_st(s, 0, add-1);
reverse(s, add+1, len-1);
erase_ed(s);
if (s[strlen(s)-1] == '.')
s[strlen(s)] = '0';
} else if (strchr(s, '/') - s >= 0) {
int add = strchr(s, '/') - s;
reverse(s, 0, add-1);
st = find_st(s, 0, add-1);
reverse(s, add+1, len-1);
erase_md(s, add+1);
for (int i = st; s[i]; i++)
if (s[i] != ' ')
putchar(s[i]);
return 0;
} else {
reverse(s, 0, len-1);
st = find_st(s, 0, len-1);
}
printf("%s", s + st);
return 0;
}
其实用 string
应该会更简单亿点,直接 stringstream
。但些都写完了就懒得再写其他方法了。