第35次csp认证第二题
#include<iostream> #include<map> #include<vector> #include<string> using namespace std; char trans[65];//0-25:A-Z 26-51:a-z 52-61:0-9 62:' ' int transnum[65];//由转换函数得到的从某字符开始到再次找到这个字符转换次数 map<char, int> ch2int; int main() { for (char ch = 'A';ch <= 'Z';ch++) { ch2int.insert({ ch,ch - 'A' }); } for (char ch = 'a';ch <= 'z';ch++) { ch2int.insert({ ch,26+ch - 'a' }); } for (char ch = '0';ch <= '9';ch++) { ch2int.insert({ ch,52+ch - '0' }); } ch2int.insert({ ' ',62 }); //完成字符到索引数的映射 string s; getline(cin, s);//初始字符串s int n;//转换串个数 vector<char> start; scanf_s("%d\n", &n); for (int i = 0;i < n;i++) { string temp ; getline(cin,temp); start.push_back(temp[1]); if (temp[1] == ' ') trans[62] = temp[2]; if (temp[1] >= 'A' && temp[1] <= 'Z') trans[temp[1] - 'A'] = temp[2]; if (temp[1] >= 'a' && temp[1] <= 'z') trans[26+temp[1] - 'a'] = temp[2]; if (temp[1] >= '0' && temp[1] <= '9') trans[52+temp[1] - '0'] = temp[2]; } //处理转换函数 for (int i = 0;i < n;i++) { for (auto it = start.begin();it != start.end();it++) { char ch_start = *it; int num = 0; while (trans[ch2int[ch_start]]) { ch_start = trans[ch2int[ch_start]]; num++; if (trans[ch2int[ch_start]] == *it) { transnum[ch2int[*it]] = num+1; break; } } } } int m;//查询个数 scanf_s("%d", &m); for (int i = 0;i < m;i++) { string ans = s; int q_num;//查询转换次数 cin >> q_num; for (int j = 1;j < s.length() - 1;j++)//对s每个字符进行转换处理 (首尾的#不处理) { int q_num_temp = q_num; char ch = s[j]; if (transnum[ch2int[ch]]) { int short_q_num = q_num % transnum[ch2int[ch]];//有转换循环的字符,其转换次数取余后再计算 while (short_q_num--) { ch = trans[ch2int[ch]];//转换 } ans[j] = ch; } else { while (q_num_temp--) { if(trans[ch2int[ch]]) ch = trans[ch2int[ch]];//转换 } } ans[j] = ch; } cout << ans << '\n'; } return 0; }
找变换的循环来减少一些字母在真正变换时的次数
用stl容器方便映射解题
注意getline与scanf、cin使用时需要对换行符进行处理!!!