1. 程式人生 > >CCF認證考試201612-3 許可權查詢題解

CCF認證考試201612-3 許可權查詢題解

// ===============================================================================
// File Name           :    ccf真題-201612-3-含註釋AC程式碼.cpp  
// Author              :    Sneexy
// Create Time         :    2017/03/02 11:31:05 
// Update Time         :    2017/03/02 11:31:05 
// CSDN blog address   :    http://blog.csdn.net/qq_33810513
// ===============================================================================

#include
#include
using namespace std;
struct Privilege
{
	string name;
	int level;
}privileges[101];
struct Role
{
	string name;
	struct Privilege pri[11];//privileges
	int priNum;
}roles[101];
struct User
{
	string name;
	struct Role rol[11];//roles
	int rolNum;
}users[101];

struct Privilege setPri(string priName)//將priName裡表示的許可權名、等級儲存
{
	struct Privilege p;
	if (priName.find(":", 0) != string::npos)//有等級
	{
		int pos = priName.find(":", 0);
		p.name = priName.substr(0, pos);
		p.level = priName.at(priName.length() - 1) - '0';
	}
	else//無等級
	{
		p.name = priName;
		p.level = -1;
	}
	return p;
}
int searchRol(string roleName, int allRoleNum)
{
	for (int i = 0; i < allRoleNum; i++)
	{
		if (roleName == roles[i].name) return i;
	}
	return -1;
}
int searchUser(string userName, int allUserNum)
{
	for (int i = 0; i < allUserNum; i++)
	{
		if (users[i].name == userName) return i;
	}
	return -1;
}

int main()
{
	int i, j, k;//臨時變數
	int allRoleNum, allUserNum;
	string priName, roleName, userName;

	//輸入privilege並儲存到 privileges[]
	int p;
	cin >> p;
	for (i = 0; i < p; i++)
	{
		cin >> priName;
		privileges[i] = setPri(priName);
	}
	//輸入role,並儲存到roles[]
	cin >> allRoleNum;
	for (i = 0; i < allRoleNum; i++)
	{
		cin >> roles[i].name >> roles[i].priNum;
		for (j = 0; j < roles[i].priNum; j++)
		{
			cin >> priName;
			roles[i].pri[j] = setPri(priName);
		}
	}
	//輸入user,並儲存到users[]
	cin >> allUserNum;
	for (i = 0; i < allUserNum; i++)
	{
		cin >> users[i].name >> users[i].rolNum;
		for (j = 0; j < users[i].rolNum; j++)
		{
			cin >> roleName;
			users[i].rol[j] = roles[searchRol(roleName, allRoleNum)];//從roles[]中尋找對應的role,匹配到此user名下
		}
	}

	//輸入查詢資訊,開始查詢
	int q;
	cin >> q;
	for (i = 0; i < q; i++)
	{
		int maxLevel = -1; //與pri同名的許可權的最高等級
		bool flag = false; //flag表示輸入的user是否有輸入的pri.因為flag不能一錯全錯,所以初始值為false
		Privilege pri1;//儲存臨時要查詢的user、role、privilege變數
		Role role1;
		User user1;
		cin >> userName >> priName;
		if (searchUser(userName, allUserNum) != -1)//存在此user
		{
			user1 = users[searchUser(userName, allUserNum)];	//根據一個攻略的程式碼滿分可知,擁有此使用者名稱的使用者只有一個
			pri1 = setPri(priName);
			//處理資料
			for (k = 0; k < user1.rolNum; k++)//遍歷User的每一個Role
			{
				role1 = user1.rol[k];
				for (j = 0; j < role1.priNum; j++)//遍歷此Role的每一個Privilege
				{
					if (role1.pri[j].name == pri1.name)//匹配
					{
						if (role1.pri[j].level == -1 && pri1.level == -1) flag = true;//許可權、查詢都無等級
						//else if(role.pri[j].level == -1 && pri.level != -1) //許可權無等級,查詢有,為預設false,故不討論
						else if (role1.pri[j].level != -1 && pri1.level == -1) //許可權有等級,查詢無
						{
							flag = true;
							if (maxLevel < role1.pri[j].level) maxLevel = role1.pri[j].level;
						}
						else if (role1.pri[j].level != -1 && pri1.level != -1) //許可權、查詢都有等級
						{			
							if (role1.pri[j].level >= pri1.level)flag = true;/*數字越大表示許可權等級越高。系統規定如果使用者具有某類某一等級的許可權,那麼他也將自動具有該類更低等級的許可權。*/
						}
					}
				}
			}
		}

		//根據是否處理資料的結果進行輸出
		if (!flag) cout << "false" << endl;
		else if (maxLevel != -1) cout << maxLevel << endl;
		else cout << "true" << endl;

	}
	return 0;
}