Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
14 kB
2
Indexable
Never
#define MAX_NAME_LEN 5
#define Open true
#define Close false
#define MAXACCOUNT 100001
#include <unordered_map>
#include <vector>
#include <string>
void mstrcpy(char dst[], const char src[]) {
	int c = 0;
	while ((dst[c] = src[c]) != '\0') ++c;
}

int mstrcmp(const char str1[], const char str2[]) {
	int c = 0;
	while (str1[c] != '\0' && str1[c] == str2[c]) ++c;
	return str1[c] - str2[c];
}

struct Account{
	char group[MAX_NAME_LEN];
	int mAsset;
	bool mode;
	int time;
	void set(int mTime, char mGroup[MAX_NAME_LEN], int mNumber, int mAsset){
		time = mTime;
		mstrcpy(group, mGroup);
		mode = Open;
		this->mAsset = mAsset;
	}
}Accounts[MAXACCOUNT];

std::unordered_map<std::string, std::vector<std::string>> hashNameToGroup;
std::unordered_map<std::string, std::vector<Account>> hashGroup;

void init(){
	hashNameToGroup.clear();
	for(auto v: hashGroup){
		for(auto vv: v.second){
			vv.mode = Close;
		}
	}
	hashGroup.clear();
}

void openAccount(int mTime, char mName[MAX_NAME_LEN], char mGroup[MAX_NAME_LEN], int mNumber, int mAsset){
	Accounts[mNumber].set(mTime, mGroup, mNumber, mAsset);
	hashNameToGroup[mName].push_back(mGroup);
	hashGroup[mGroup].push_back(Accounts[mNumber]);
}

int closeAccount(int mTime, int mNumber){
    return 0;
}

int sendByNumber(int mTime, int mNumber, int mReceiveNumber, int mValue){
    return 0;
}

int sendByName(int mTime, int mNumber, char mReceiveName[MAX_NAME_LEN], int mValue){
    return 0;
}

void sendBonus(int mTime, char mGroup[MAX_NAME_LEN], int mValue){

}


int main(){
	init();
	openAccount(1, "lee", "hr", 20, 200);
	openAccount(2, "kim", "hr", 21, 210);
	openAccount(3, "kim", "dev", 11, 110);
	openAccount(4, "kim", "dev", 12, 120);
	openAccount(5, "kim", "hr", 22, 220);
	closeAccount(6, 22); // 220
	sendByNumber(7, 22, 20, 10);
	openAccount(8, "kim", "hr", 23, 230);//-1
	sendByNumber(9, 20, 11, 300);//-1
	sendBonus(10, "dev", 100);
	sendByName(11, 21, "kim", 50);//270
	sendByName(12, 20, "kim", 50);//320
	closeAccount(13, 12);//320
	sendByName(14, 2, "kim", 40);//200
	sendBonus(15, "hr", 30);
	sendByNumber(16, 20, 23, 11);//241
	sendByName(17, 20, "kim", 10);//251
	
	return 0;
}

//
You are required to develop a money transfer service that allows clients constitute groups and transfer money to one another. The service is composed of the following features.


 


- If a client opens a bank account to use in a group, the client automatically joins the group.


- When an account is being created, the name of the client who holds the account, the name of the group the account belongs, the account number, and the amount of money to be transferred are entered.


- One client can join multiple groups and open multiple accounts to use in one group. Clients can close their accounts, as well. But, it is guaranteed that not all the accounts of an account holder that belong to the holder’s particular group are closed.


- The money transfer service enables clients to transfer money to a certain account using the account number or the name of the account holder. When money is transferred to an account using the holder’s name, the money goes into the account with the highest priority among the holder’s accounts.


- The service provider may grant bonus to a particular group of clients. The bonus transferred through the service is sent to the account with the highest priority among the holder’s accounts that belong to a particular group.


 


* The priority of an account is decided based on the time of balance change and whether any money was transferred at the time of balance change.


  - The time of balance change refers to the time when the balance of the account changed most recently. This value is updated to the most recent time when money is transferred to the account for the first time since its opening, when the balance decreases after transferring money from the account, when the balance increases after receiving money transfer, or when the service provider sent bonus to the account.


  - The bigger the time of balance change is, the higher the priority is. If the time of balance change is the same, an account that received money has a higher priority than another account that sent money out. The account to receive money can be decided based on this condition only.


 


Write a program that runs a simulation of money transfer service described as above.


 


The following is the description of API to be written in the User Code.


※ The function signature below is based on C/C++. As for Java, refer to the provided Solution.java and UserSolution.java.


void init()

This function is called once in the beginning of each test case.

In the beginning of each test case, the time starts from 0. Every time one of the following functions is called, the time increases by 1 and delivered in the value of mTime.

void openAccount(int mTime, char mName[], char mGroup[], int mNumber, int mAsset)

This function creates an account of a client and deposit the given amount of money into the account. The name of the account holder, the name of the group the account belongs, the account number, and the amount of money to be deposited in the account are given.

The names of clients and groups are composed of lowercase alphabet letters only. The length is from 2 to 4.

The name of clients and groups ends with '\0'. It is not counted when measuring the length.

No same account number is given. That is, only a bank account number that has never been generated before is given.

 

Parameters

  mTime: Current time when the function is called

  mName: Name of the bank account holder (2 ≤ |mName| ≤ 4, |a| means the length of the string a)

  mGroup: Name of the group to which the account belongs (2 ≤ |mGroup| ≤ 4)

  mNumber: Account number to be generated (1 ≤ mNumber ≤ 100,000)

  mAsset : Amount of money to be deposited in the created account (1 ≤ mAsset ≤ 1,000)

int closeAccount(int mTime, int mNumber)

This function deletes a bank account. The account number of the bank account to be closed is given.

A bank account number that was deleted or has never been generated is not given.

It is guaranteed that not all the accounts of an account holder that belong to the holder’s particular group are closed.

 

Parameters

  mTime: Current time when the function is called

  mNumber: Account number to be deleted

 

Returns

  The balance of the removed account is returned.

int sendByNumber(int mTime, int mNumber, int mReceiveNumber, int mValue)

This function sends money using an account number. The account number of the bank account from which the money is sent, the account number of the bank account receiving the transferred money, and the amount of money being transferred are given.

 

Parameters

  mTime: Current time when the function is called

  mNumber: Account number of the bank account from which the money is sent

mReceiveNumber: Account number of the bank account receiving the transferred money

mValue: Amount of money being transferred (1 ≤ mValue ≤ 1,000)

 

Returns

  If money is successfully transferred, the balance in the account that received the money is returned.

  Money transfer fails in the following cases. In such cases, -1 is returned.

  - When the account number of the bank account from which the money is sent does not exist

  - When the account number of the bank account that received the money does not exist

  - When the amount of money being transferred is greater than the balance in the bank account from which the money is sent

int sendByName(int mTime, int mNumber, char mReceiveName[], int mValue)

This function sends money into the account with the highest priority among the accounts owned by an account holder with the given name. The account number of the bank account from which the money is sent, the name of the account holder who receives the money, and the amount of money being transferred are given.

 

Parameters

  mTime: Current time when the function is called

  mNumber: Account number of the bank account from which the money is sent

  mReceiveName: Name of the account holder who receives the money

  mValue: Amount of money being transferred (1 ≤ mValue ≤ 1,000)

 

Returns

  If money is successfully transferred, the function returns the balance of the bank account to which the money is sent.

  Money transfer fails in the following cases. In such cases, -1 is returned.

  - When the account number of the bank account from which the money is sent does not exist

  - When the name of the account holder who will receive the money does not exist

  - When the amount of money being transferred is greater than the balance in the bank account from which the money is sent

void sendBonus(int mTime, char mGroup[], int mValue)

The service provider sends bonus to clients. For each client, the bonus is sent to the account with the highest priority among his/her all accounts that belong to a certain group. The name of the group to which the bonus will be sent and the amount of bonus are given.

It is guaranteed that the number of accounts that belong to the given group is one or bigger.

 

Parameters

  mTime: Current time when the function is called

  mGroup: Name of group to which the bonus will be sent

  mValue: Amount of bonus (1 ≤ mValue ≤ 1,000)


//
#define MAX_NAME_LEN (4+1)
 
 
struct Trie{
    struct Node{
        int num;
        Node *next[26];
        Node(){
            num = -1;
            for(int i=0;i<26;i++) next[i] = 0;
        }
        Node* add(char *str){
            if(*str){
                if(!next[*str-'a']) next[*str-'a'] = &Trie::nodes[Trie::Nnodes++];
                return next[*str-'a']->add(str+1);
            }
            return this;
        }
        Node* get(char *str){
            if(*str){
                if(!next[*str-'a']) return nullptr;
                return next[*str-'a']->get(str+1);
            }
            return this;
        }
        void clear(){
            for(int i=0;i<26;i++) if(next[i]){
                next[i]->clear();
                next[i] = 0;
            }
            num = -1;
        }
    };
    static Node nodes[200000];
    static int Nnodes;
    int count;
    Node root;
 
 
    int add(char *str){
        Node *node = root.add(str);
        if(node->num == -1) node->num = count++;
        return node->num;
    }
    int get(char *str){
        Node *node = root.get(str);
        if(node == nullptr) return -1;
        return node->num;
    }
    void clear(){
        root.clear();
        count = 0;
    }
};
Trie::Node Trie::nodes[200000];
int Trie::Nnodes;
 
 
struct Stack{
    struct Node{
        int value;
        Node* parent;
        Node(){}
        Node(int value, Node* parent):value(value), parent(parent){}
    };
    Node *ed;
    int size;
    static Node nodes[5000000];
    static int Nnodes;
    
    Stack():ed(nullptr), size(0){}
    void push(int value){
        Node *node = &nodes[Nnodes++];
        *node = {value, ed};
        ed = node;
        size++;
    }
    int pop(){
        int res = ed->value;
        Node *last = ed;
        ed = ed->parent;
        size--;
        return res;
    }
    int top(){
        return ed->value;
    }
    bool empty(){
        return size == 0;
    }
    void clear(){
        while(!empty()) pop();
    }
};
 
 
Stack::Node Stack::nodes[5000000];
int Stack::Nnodes;
 
 
struct Account{
    int user, group, asset;
    bool active;
};
 
 
Trie Tname, Tgroup;
Account account[100001];
Stack account_u[30000], account_g[20][30000];
int users[20][30000], Nusers[20];
int chk_user_group[20][30000];
 
 
int get_highest(Stack &stack){
    while(!stack.empty()){
        int number = stack.top();
        if(account[number].active) return number;
        stack.pop();
    }
    return -1;
}
 
 
void init(){
    Tname.clear();
    Tgroup.clear();
    for(int i=0;i<=100000;i++) account[i] = {0, 0, 0, false};
    for(int i=0;i<30000;i++) account_u[i].clear();
    for(int i=0;i<20;i++) for(int j=0;j<30000;j++) account_g[i][j].clear();
    for(int i=0;i<20;i++){
        for(int j=0;j<Nusers[i];j++) chk_user_group[i][users[i][j]] = 0;
        Nusers[i] = 0;
    }
    Stack::Nnodes = 0;
    Trie::Nnodes = 0;
}
void updateAccount(int number){
    int user = account[number].user;
    int group = account[number].group;
    account_u[user].push(number);
    account_g[group][user].push(number);
}
void openAccount(int mTime, char mName[MAX_NAME_LEN], char mGroup[MAX_NAME_LEN], int mNumber, int mAsset){
    int user = Tname.add(mName);
    int group = Tgroup.add(mGroup);
    account[mNumber] = {user, group, mAsset, true};
    updateAccount(mNumber);
    if(!chk_user_group[group][user]){
        chk_user_group[group][user] = 1;
        users[group][Nusers[group]++] = user;
    }
}
 
 
int closeAccount(int mTime, int mNumber){
    account[mNumber].active = false;
    return account[mNumber].asset;
}
 
 
int sendByNumber(int mTime, int mNumber, int mReceiveNumber, int mValue){
    if(!account[mNumber].active ||
       !account[mReceiveNumber].active ||
       account[mNumber].asset < mValue) return -1;
    account[mNumber].asset -= mValue;
    account[mReceiveNumber].asset += mValue;
    updateAccount(mNumber);
    updateAccount(mReceiveNumber);
    return account[mReceiveNumber].asset;
}
 
 
int sendByName(int mTime, int mNumber, char mReceiveName[MAX_NAME_LEN], int mValue){
    int user = Tname.get(mReceiveName);
    if(user == -1) return -1;
    int mReceiveNumber = get_highest(account_u[user]);
    return sendByNumber(mTime, mNumber, mReceiveNumber, mValue);
}
 
 
void sendBonus(int mTime, char mGroup[MAX_NAME_LEN], int mValue){
    int group = Tgroup.get(mGroup);
    for(int i=0; i<Nusers[group]; i++){
        int user = users[group][i];
        int number = get_highest(account_g[group][user]);
        account[number].asset += mValue;
        updateAccount(number);
    }
}