学习C++从娃娃抓起!记录下在学而思小猴编程学习过程中的题目,记录每一个瞬间。侵权即删,谢谢支持!
附上汇总贴:小猴编程C++ | 汇总-CSDN博客
【题目描述】
老师给小明布置了一个任务,要他构造一个数列 a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,…,an,满足以下条件:
(1) a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,…,an的值恰好是1~n,每种1个。
(2)另有一个长为n-1的字符串s,它只包含三种字符:‘I’,‘D’,‘?’。我们用 s i s_i si表示字符串s的第i个字符(下标从1开始)
如果 s i = I s_i=I si=I,那么 a i < a i + 1 a_i\lt a_{i+1} ai<ai+1。
如果 s i = D s_i=D si=D,那么 a i > a i + 1 a_i\gt a_{i+1} ai>ai+1。
如果 s i = ? s_i=? si=?,那么对 a i a_i ai和 a i + 1 a_{i+1} ai+1的大小关系没有要求。
小明想要构造出满足上述条件的字典序最小的数列。
【输入】
第1行,1个正整数n。
第2行,1个长为n-1的字符串s。
【输出】
用1行输出满足条件的字典序最小的数列,数之间用空格分隔。
【输入样例】
4
DDI
【输出样例】
3 2 1 4
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int n, a[100005];
string s;
int main()
{
cin >> n >> s;
for (int i=1; i<=n; i++) { // 创建a序列
a[i] = i;
}
for (int i=0; i<s.size(); i++) { // 遍历s字符串
int l, r; // 定义起始和结束位置
if (s[i]=='D') { // 如果等于'D'
l = i, r= i;
while (s[r]=='D') { // 找到连续的D
r++;
}
i = r-1; // 修改i,下次就从r的下一个位置开始遍历
l = l+1, r = r; // 为对a序列进行反转,修正l和r
reverse(a+l, min(a+n+1,a+r+2)); // 类似sort(a+1,a+n+1),即对[l,r+1]范围内序列进行反转
}
}
for (int i=1; i<=n; i++) { // 输出整个序列
cout << a[i] << " ";
}
cout << endl;
return 0;
}
【运行结果】
4
DDI
3 2 1 4