**
题目链接
**
题目:1067 试密码 (20分)
当你试图登录某个系统却忘了密码时,系统一般只会允许你尝试有限多次,当超出允许次数时,账号就会被锁死。本题就请你实现这个小功能。
输入格式:
输入在第一行给出一个密码(长度不超过 20 的、不包含空格、Tab、回车的非空字符串)和一个正整数 N(≤ 10),分别是正确的密码和系统允许尝试的次数。随后每行给出一个以回车结束的非空字符串,是用户尝试输入的密码。输入保证至少有一次尝试。当读到一行只有单个 # 字符时,输入结束,并且这一行不是用户的输入。
输出格式:
对用户的每个输入,如果是正确的密码且尝试次数不超过 N,则在一行中输出 Welcome in,并结束程序;如果是错误的,则在一行中按格式输出 Wrong password: 用户输入的错误密码;当错误尝试达到 N 次时,再输出一行 Account locked,并结束程序。
输入样例 1:
Correct%pw 3
correct%pw
Correct@PW
whatisthepassword!
Correct%pw
输出样例 1:
Wrong password: correct%pw
Wrong password: Correct@PW
Wrong password: whatisthepassword!
Account locked
输入样例 2:
cool@gplt 3
coolman@gplt
coollady@gplt
cool@gplt
try again
输出样例 2:
Wrong password: coolman@gplt
Wrong password: coollady@gplt
Welcome in
思路:这个题目并不是难,直接输入,然后比较密码的区别.
代码:
#include <iostream>
using namespace std;
int main()
{
string a[15];
string s, x;
int n, i, j, len1, len2, ok, ans = 0, flag = 1, cnt = 0;
cin >> s >> n;
len1 = s.size();
while (cin >> x, x != "#" && flag)
{
a[cnt++] = x;
}
for (i = 0; flag && i < cnt; i++)
{
ok = 1;
len2 = a[i].size();
if (len1 != len2)
{
ok = 0;
cout << "Wrong password: " << a[i] << endl;
ans++;
}
for (j = 0; ok && j < len1; j++)
{
if (s[j] != a[i][j])
{
ok = 0;
cout << "Wrong password: " << a[i] << endl;
ans++;
}
}
if (ok)
{
cout << "Welcome in" << endl;
flag = 0;
}
else if (ans == n)
{
cout << "Account locked" << endl;
flag = 0;
}
}
return 0;
}
此时第二个测试点和最后一个测试点错误,且第五个错误是数组越界的问题,题目的N是小于10的,所以我刚开始判断的时候就以为只输入10个密码,但是N的实际意思是系统允许尝试的次数,意识是最多只能检测我输入密码的前10个,并不是密码只输入10个,当你把a数组范围调大一点的时候,就是答案错误了。所以我在仔细看了一下题目发现这一句话“随后每行给出一个以回车结束的非空字符串”,然后又百度了一下,查到了这个知识点:
*scanf("%[^\n]%*c",str)表示读入一行字符串。
表示"非",[\n]表示读入换行字符就结束读入。
表示该输入项读入后不赋予任何变量,即scanf("%[^\n]%c")表示跳过一行字符串。
所以我又写了一个版本,代码如下:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
char a[25],b[10000];
int main()
{
bool flag = true;
int sum = 0, n;
cin >> a >> n;
while(flag)
{
getchar();
scanf("%[^\n]",b);
if(b[0] == '#' && b[1] == '\0')
{
flag = flag;
}
else
{
sum++;
if(strcmp(a,b) == 0)
{
cout << "Welcome in" << endl;
flag = 0;
}
else
{
cout << "Wrong password: " << b << endl;
if(sum == n)
{
cout << "Account locked" << endl;
flag = 0;
}
}
}
}
return 0;
}
但是还是有问题,第二个测试点运行超时。思考了很久没清楚是什么问题,就百度了一下这个题目然后找到了别人的只是我写的flag = 0 写的是break(break可以直接退出,速度确实快于逻辑变量的修改,但是我上学的老师叫我们不要使用break,速度确实会快,但是会让代码的逻辑很糟糕,continue还有goto一样,好用是好用,但是会让代码很难理解,建议少用,甚至不用)
总结:1.学习了scanf("%[^\n]%*c",str)的使用
2.break能提速,但是建议少用!!!
第一次写博客,写的比较随意,希望大家多多支持啊,谢谢!!