LuoguP7478 【A】StickSuger 题解
Content
给定一个长度为 \(n\) 的仅包含小写字母的字符串 \(s\),请找到一个二元组 \((i,j)\)(\(i<j\))使得在交换字符串 \(s\) 的第 \(i\) 个和第 \(j\) 个字符后会使新的字符串比原字符串的字典序大。若有多个满足要求的 \((i,j)\),输出 \(i\) 最大的那一个,如果仍有多个方案,输出 \(j\) 最大的那一个。
数据范围:\(1\leqslant n\leqslant 10^6\)。
Solution
先从后往前扫,扫到第一个 \(i\in[1,n)\) 使得 \(s_i<s_{i+1}\)(此处为 ASCII 码比较),记录下这个位置 \(p\) 。然后判断是否存在这个位置,如果不存在输出 -1
。
否则,再从 \(n\) 开始往后扫到 \(p+1\),扫到第一个 \(i\in[p+1,n]\) 使得 \(s_i>s_p\)(同上)。此时 \((i,p)\) 即为满足要求的二元组,也就是答案,直接输出即可。
Code
char s[1000007];
int main() {
int n = Rint, fl = -1; scanf("%s", s + 1);
R(int, i, n - 1, 1) if(s[i] < s[i + 1]) {fl = i; break;}
if(fl == -1) return printf("-1"), 0;
print_space(fl);
R(int, i, n, fl + 1) if(s[i] > s[fl]) return write(i), 0;
return 0;
}