#旋转加密解密#acwing#字符串字符数组#变态的测试用例
链接https://www.acwing.com/problem/content/3408/
建议采用增量开发,测试用例非常变态,务必确保写完的函数不出问题,不然要debug好久:)
/*加密消息需要三个整数密钥,k1、k2和 k3。 将字母 a∼i分为第一组,字母 j∼r分为第二组,字母 s∼z与下划线 _ 分为第三组。 在对消息进行加密时,要将消息中涉及到的每个组的字符,在组内进行向左旋转 ki个位置(位于组内相对位置最左端的字符向左移动一位会到组内相对最右端的位置)。 每个组之间都是相互独立的,也就是说在旋转操作完成后,每个组的字符所占据的位置集合不会发生变化,只是组内各字符的相对位置可能发生变化。 解密即每个组内进行向右旋转 ki位置。 例如,在 ki值分别为 2,3,1时,对消息 the_quick_brown_fox 进行加密,我们可以得到加密后的字符串 _icuo_bfnwhoq_kxert。*/ #include <cstdio> #include <iostream> #include <string> #include <vector> using namespace std; void partition(string a,vector<int> &vec1,vector<int> &vec2,vector<int> &vec3){ for(int i=0;i<a.size();i++){ if (a[i]>='a'&&a[i]<='i'){ vec1.push_back(i); } else if(a[i]>='j'&&a[i]<='r'){ vec2.push_back(i); } else{ vec3.push_back(i); } } } void Rrotation(string &a,vector<int> &vec,int offset){ vector<char> tmp; if(vec.size()==0) return; else{ int b=vec.size(); for(int j=vec.size()-offset%b;j<vec.size();j++){ //右移超过边界的部分 tmp.push_back(a[vec[j]]); } for(int j=vec.size()-offset%b-1;j>=0;j--){ //原地右移剩下元素 a[vec[offset%b+j]]=a[vec[j]]; //必须从右往左依次挪动元素防止覆盖 } for(int j=0;j<tmp.size();j++){ a[vec[j]]=tmp[j]; } } } int main(){ string str; int k1,k2,k3; while(scanf("%d%d%d",&k1,&k2,&k3)!=EOF){ if (k1==0&&k2==0&&k3==0) { break; } char arr[1000]={0}; scanf("%s",arr); str=arr; vector<int> vec1,vec2,vec3; partition(str,vec1,vec2,vec3); Rrotation(str,vec1,k1); Rrotation(str,vec2,k2); Rrotation(str,vec3,k3); printf("%s\n",str.c_str()); } return 0; }