OJ 1576 user password login continuous failure locking problem

Posted by msinternet on Wed, 29 Dec 2021 19:30:45 +0100

#include<iostream>
#include<vector>
#include<string>
#include<list>
#include<utility> 
#include<stdlib.h>
using namespace std;

bool isfind_ch(vector<pair<char, int>> vec, char ch) {
	//Is there a pair with ch as the key in
	char tmpt;
	tmpt = toupper(ch);
	//All uppercase storage
	for (int i = (vec.size() - 1); i >= 0; i -= 1) {
		if (vec.at(i).first == tmpt)
			return 1;
	}
	return 0;
}

int find1(vector< pair<char, int> > vec, char ch) {
	char tmpt;
	tmpt = toupper(ch);
	for (int i = (vec.size() - 1); i >= 0; i -= 1) {
		if (vec.at(i).first == tmpt)
			return i;
	}
	return 0;
}

int main(void) {
	string tem;
	int num1,num2;
	vector<string> tmpt;
	while (cin >> tem) {
		tmpt.push_back(tem);
		if (cin.get() == '\n')
			break;
	}
	tem = tmpt.at(0);
	num1 = stoi(tmpt.at(1));
	num2 = stoi(tmpt.at(2));
	vector<pair<char, int>> newvec;

	if (num1 > tem.size()) {
		cout << '-';
		exit(100);
	}
		

	for (int i = (tem.size() - 1); i >= 0; i -= 1) {
		if (isfind_ch(newvec, tem.at(i)) == 0) {
			newvec.push_back(make_pair(toupper(tem.at(i)), 0));	
			//Put all the letters in the vector
		}
	}


	int n = 0, k;
	
	while (true) {
		k = tem.size() - n * num1;
		if (k <= num1) {
			break;
		}
		else
			n++;
	}
	k = 0;
	int x = 0;

	for (int i = (tem.size()-1); i >= 0 ; i -= 1) {
			x = find1(newvec, tem.at(i));
			if (i < (n)*num1 && i == n * num1 - 1) {
				for (int j = 0; j < newvec.size(); j++) {
					if (tem.substr(n * num1, num1).find(newvec.at(j).first) == -1) {
						newvec.at(j).second = 0;
					}

				}
				n--;
			}
			if (tem.at(i) >= 'a' and tem.at(i) <= 'z') {
				//Clear lowercase
				newvec.at(x).second = 0;
			}
			else
				newvec.at(x).second += 1;
	}
	int q = 0;
	list<char> list1;
	for (int i = 0; i < newvec.size(); i += 1) {
		if (newvec.at(i).second >= num2 && (tem.substr(0, num1).find(newvec.at(i).first) != -1)) {
			list1.push_back(newvec.at(i).first);
			q = 1;
		}
	}
	list1.sort();
	int m = list1.size();
	for (int i = 0; i < m; i++ ) {
		cout << list1.front();
		list1.pop_front();
	}

	if(q == 0)
		cout << '-';
	return 0;
}
//aABCFDEDAABBCCDDEEFFFF 6 3
//BD

It is assumed that the account number of each user is a lowercase English letter. When the user logs in successfully, the account number in lowercase letters of the user is recorded in the log. If the user fails to log in, the corresponding capital letters of the user will be recorded in the log. In this way, the log is actually a string. Each time new content is recorded, uppercase or lowercase letters are appended to the beginning of the string. For example, the current log is ABDDCabcdAAB. When user D fails to log in, the log changes to dabdcabcdaab. If the user enters the wrong password, the user counter + 1, When in the previous window period If the user does not log in again within (6), the counter will clear to 0 when entering the window. If the user has entered an error before, logs in again, and the password is correct, the counter will clear to 0, even if the number of consecutive errors is reached. For the log DABDDCabcdAAB, set the window period to 6, the login information of the current window period is DABDDC, and the login information of the previous window period is abcda A. And so on. The current window is always the first window.

In order to avoid hackers constantly testing the password of an account, You need to immediately lock the account with the wrong password in the current window period and have continuously entered the wrong password n times (the continuous wrong password is not necessarily in the current window) and get the account (that is, the returned account must be the account in the current window period). If the window is 6, n is 3, and the current log is DABDCAabcDAAB, then the current window period is DABDCA, and account D should be locked because the previous window period d was entered incorrectly once. A is not locked because a entered incorrectly only twice in the current window period, and the previous window period was finally entered correctly.

Please implement the algorithm, input the string log s, the window period Size w, the number of consecutive wrong passwords n, output the capital letters of all qualified accounts, and output all accounts in alphabetical order. If there is no qualified account, the output is -.

For example: Enter: bzcbbzcczdddabccaaba 10 3

Output: C

Analysis: the current window period is: bzcbbzccz. Obviously, B finally lost it correctly and has been cleared. The times of Z continuous transmission error is 2, and C continuous transmission error is 3, which shall be locked.

Input: DABDCAabcDAAB 6 3

Output: D

Analysis: the current window period is DABDCA, D. the previous window period is wrongly entered once, and the current window period is wrongly entered twice. It should be locked. A. wrong input twice in a row. BC is wrong only once.

Input: DABDCAadbcDAAB 6 3

Output:-

Analysis shows that the current window period is DABDCA and the previous window period is adbcDA. Obviously, DABC does not meet the conditions

Input: abbbcccaaa 4 3

Output:-

Analysis: A has no input in the previous window period, and the number of input errors is cleared to 0 at the beginning of this window period

The main problem is that the final output should be output in dictionary order. If the number of letters is stored in ch[26], there is no problem

However, if you write it in STL, you won't bother to think about sort at last. There is a lot of room for time optimization

Topics: C++ Algorithm