蓝桥杯B组C++ 2012-密码发生器 The sixth day
发现对二维数组指针传参还很模糊,推荐文章
第八题:密码发生器
在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:
如果为了好记用生日吧,容易被破解,不安全;
如果设置不好记的密码,又担心自己也会忘记;如果写在纸上,担心纸张被别人发现或弄丢了...
这个程序的任务就是把一串拼音字母转换为6位数字(密码)。
我们可以使用任何好记的拼音串(比如名字,王喜明,就写:wangximing)作为输入,
程序输出6位数字。
第一步. 把字符串6个一组折叠起来,比如wangximing则变为:
wangxi
ming
第二步. 把所有垂直在同一个位置的字符的ascii码值相加,得出6个数字,
如上面的例子,则得出:
228 202 220 206 120 105
第三步. 再把每个数字“缩位”处理:就是把每个位的数字相加,
得出的数字如果不是一位数字,就再缩位,直到变成一位数字为止。
例如: 228 => 2+2+8=12 => 1+2=3
上面的数字缩位后变为:344836, 这就是程序最终的输出结果!
要求程序从标准输入接收数据,在标准输出上输出结果。
输入格式为:第一行是一个整数n(<100),表示下边有多少输入行,
接下来是n行字符串,就是等待变换的字符串。
输出格式为:n行变换后的6位密码。
例如,输入:
5
zhangfeng
wangximing
jiujingfazi
woaibeijingtiananmen
haohaoxuexi
则输出:
772243
344836
297332
716652
875843
具体的做法,代码中已经做了注释。注释中的编号就是主要思想。
#include<iostream>
#include<cstring>
using namespace std;
#define N 30
void f(char * p){
string de= p; //接收需要处理的这一行字符串;
int n=strlen(p),x,y;
char a[n/6+1][6]; //将字符串转换为字符数组
int b[6]={0,0,0,0,0,0}; //存储将此列字符的ascii相加之后的值
int c[6]={0,0,0,0,0,0}; //对每个值得每一位相加
for(x=0;x<n/6+1;x++){ //1.字符串存储到字符数组中
for(y=0;y<6;y++)
if(p!='\0'){
a[x][y]=*p;
p=p+1;
}
}
/* for(x=0;x<n/6+1;x++){
for(y=0;y<6;y++){
cout<<a[x][y];
}
cout<<endl; //输出转换后的数组
}*/
for(y=0;y<6;y++){ //2.对每列字符的ascii相加
x=0;
do{
b[y]+=int(a[x][y]);
x++;
}while(x<n/6);
if(y<n%6){
b[y]+=int(a[x][y]); //由于最后一行的字符可能没有填满6个,因此要判断
}
}
cout<<endl;
/* for(x=0;x<6;x++){
cout<<b[x]<<endl;
} */ //检验
for(x=0;x<6;x++){ //3.将每个值得每位相加
while(b[x]>0){
c[x]=c[x]+b[x]%10;
b[x]/=10;
}
int m=0;
while(c[x]/10>0){
m=m+c[x]%10;
c[x]=c[x]/10;
}
c[x]=m+c[x];
cout<<c[x];
}
}
int main() {
int num,i,ans;
cin>>num;
char a[num][N];
for(i=0;i<num;i++){
cin>>a[i];
}
for(i=0;i<num;i++){
f(a[i]);
}
return 0;
}
结果如下:【输入】+【输出】
分析
看了一下别人带代码,第一感觉,比我的短好多,肯定使用很多tips代替了我的冗余。主要分析到代码注释。如下是参考其他实现过程,在计算每给值的每位和时候,用到了递归,准确度高,很是厉害。
参考代码来自:https://blog.youkuaiyun.com/qq_18841761/article/details/107776377
#include <iostream>
#include <vector>
using namespace std;
int work(int x)
{
if (x < 10)
return x;
int sum = 0;
while (x)
{
sum += x % 10;
x /= 10;
}
return work(sum); //5.使用递归,对相加之后的结果在次相加,知道为个位数。
}
int main()
{
int n, sum;
string str;
cin >> n;
while (n--) //1.直接输入的时候就运算
{
cin >> str;
vector<int> v[6]; //2.使用C++STL, v数组中有两个元素v[0],v[1]...,v[5],每个元素又是一个vector<int>类型的数组。
for (int i = 0; i < str.size(); i++)
{
v[i % 6].push_back(str[i]); //3.让输入字符串以6列顺序排列后,每列分别进入v[i%6]
}
for (int i = 0; i < 6; i++)
{
sum = 0;
for (int j = 0; j < v[i].size(); j++)
{
sum += v[i][j]; //4.让每个v[i]中的字符ascii相加
}
cout << work(sum); //5.6.对ascii相加结果划算为1位
}
cout << '\n';
}
return 0;
}