题目大意:给出一个字符串s,从第一个字符开始,每次可以移动到任意一个字符,费用为两个字符的差值,问在费用最低的情况下,怎么用最多的步数到字符串最后一个字符
思路:费用最小值就等于第一个字符到最后一个字符的费用,要想步数最多,就要依次经过头尾两个字符中间的字符,用一个结构体储存字符和他在字符串中的位置,如果头字符大于尾字符,就按字符从大到小排序,否则按从小到大排序,然后遍历排序后的数组,找到头元素后,记录步数,将字符位置记录到数组里,知道找到尾字符后退出循环
- #include
- #include
- #include
- using namespace std;
- const int N = 2e5 + 5;
- struct ch
- {
- char c;
- int po;
- }a[N];
- int p[N];
- bool cmp(ch a, ch b)
- {
- if (a.c == b.c)
- return a.po < b.po;
- return a.c > b.c;
- }
- bool cmp2(ch a, ch b)
- {
- if (a.c == b.c)
- return a.po < b.po;
- return a.c < b.c;
- }
- int main()
- {
- int t;
- cin >> t;
- while (t--)
- {
- string s;
- cin >> s;
- int len = s.length();
- int cnt = 0;
- for (int i = 0; i < len; i++)
- {//a储存字符和字符的位置
- a[++cnt].c = s[i];
- a[cnt].po = cnt;
- }
- if (s[0] > s[len - 1])
- {//头字符大于尾字符就从大到小排序
- sort(a + 1, a + len + 1, cmp);
- }
- else
- {
- sort(a + 1, a + len + 1, cmp2);
- }
- printf("%d", abs(s[0] - s[len - 1]));
- int ans = 0;
- bool temp = 0;
- for (int i = 1; i <= len; i++)
- {
- if (!temp&&a[i].c == s[0])
- {//找到了头字符
- temp = 1;
- p[++ans] = a[i].po;
- }
- else if (a[i].po == len)
- {//找到了尾字符
- p[++ans] = a[i].po;
- break;
- }
- else if (temp)
- {//头字符和尾字符之间的元素
- p[++ans] = a[i].po;
- }
- }
- printf(" %d\n", ans);
- for (int i = 1; i <= ans; i++)
- {
- printf("%d ", p[i]);
- }
- printf("\n");
- }
- return 0;
- }