1. 程式人生 > >ccf201612-3許可權查詢(90分)

ccf201612-3許可權查詢(90分)

        相當複雜的模擬題,有一個點不懂,就是輸入的p段不知道有什麼用,既然後面輸入的角色段裡的許可權都會包含在p段裡,那這個p段感覺沒什麼用,所以我只是做了接收字串,沒有做任何處理,可能扣的10分就來自這裡吧。

        定義了三個結構體,分別表示許可權,角色,使用者,來作為資料結構接收資料。剩下的就是模擬和查找了。第一遍只有70分,然後我認認真真的寫了一遍註釋,找出了一處問題就是在輸入不分等級的許可權查詢時,若這個許可權本身的分等級的,那麼要輸出最大的等級,而我忽略了這一點。不得不說,認認真真寫一遍註釋可以幫助自己再一次理清程式的邏輯順序。更改後得了90分,程式碼如下,註釋非常詳細:

#include<iostream>
#include<vector>
using namespace std;
//表示許可權的結構體 
struct pri
{
	string cat;//許可權名 
	char level;//許可權的等級,若不分等級則值為‘-’ 
};
//表示角色的結構體 
struct role
{
	string name;//角色名 
	pri a[110];//角色所帶的許可權 
	int num;//本角色所帶許可權的數量 
}ro[110];//臨時儲存角色的陣列。
//表示使用者的結構體 
struct user
{
	string name;//使用者名稱 
	role a[110];//使用者所擁有的角色 
	int num;//本使用者所擁有的角色數量 
}us[110]; 
int main()
{
	int p;
	cin>>p;
	string temp;
	while(p--)
		cin>>temp;
	//輸入角色和他所帶的許可權 
	int r;
	cin>>r;
	for(int i=0;i<r;i++)
	{
		//角色名na和角色所帶的許可權數cate 
		string na,temp;
		int cate,pos;
		cin>>na>>cate;
		//先將輸入的角色臨時儲存到陣列中 
		ro[i].name=na;
		ro[i].num=cate;
		//接收該角色所帶的許可權 
		for(int j=0;j<cate;j++)
		{
			//許可權名 
			cin>>temp;
			//若不分等級 
			if((pos=temp.find(":"))==-1)
			{
				ro[i].a[j].cat=temp;
				ro[i].a[j].level='-';
			}
			//若分等級
			else
			{
				int k;
				//判斷之前是否輸入過這個許可權 
				for(k=0;ro[i].a[k].cat!=temp && k<j;k++);
				//若沒輸入過這個許可權,則直接新增到陣列中 
				if(k==j)
				{
					ro[i].a[k].cat=temp.substr(0,pos);
					ro[i].a[k].level=temp[temp.length()-1];
				}
				//若輸入過,則更新他的值 
				else
					ro[i].a[k].level=temp[temp.length()-1]>ro[i].a[k].level?temp[temp.length()-1]:ro[i].a[k].level;
			}
		}
	}
	//輸入使用者 
	int u;
	cin>>u;
	for(int i=0;i<u;i++)
	{
		//使用者名稱na和使用者所擁有的角色數num 
		string na,temp;
		int num,k;
		cin>>na>>num;
		us[i].name=na;
		us[i].num=num;
		for(int j=0;j<num;j++)
		{
			cin>>temp;
			//在許可權陣列中找到這個許可權,新增到使用者中 
			for(k=0;ro[k].name!=temp;k++);
			us[i].a[j]=ro[k];
		}
	}
	//輸入查詢 
	int q;
	cin>>q;
	while(q--)
	{
		//查詢的使用者qn和查詢的許可權qp 
		int pos,i;
		string qn,qp;
		cin>>qn>>qp;
		//找到第i個使用者的名字為qn
		for(i=0;us[i].name!=qn && i<u;i++);
		//判斷要查詢的許可權qp是否帶了等級
		if((pos=qp.find(":"))==-1)
		{
			//定義flag為true表示沒有找到許可權或者該許可權分等級,flag為false表示到了許可權而且該許可權不分等級 
			bool flag=true;
			int k;
			char max='+'; 
			//對使用者下的每個角色進行遍歷
			for(int j=0;j<us[i].num && flag;j++)
			{
				//對每個角色查詢是否有qp許可權,找最大值
				for(k=0;k<us[i].a[j].num;k++)
				{
					if(us[i].a[j].a[k].cat==qp)
					{
						if(us[i].a[j].a[k].level=='-')
						{
							cout<<"true"<<endl;
							flag=false;
							break;
						}
						else
							max=max>us[i].a[j].a[k].level?max:us[i].a[j].a[k].level;
					}
				}
			}
			//flag為true表示沒有找到許可權或者該許可權分等級,max為+表示他沒有被改變過,則表示沒有找到許可權,就輸出false;否則輸出max 
			if(flag)
			{
				if(max!='+')
					cout<<max<<endl;
				else
					cout<<"false"<<endl;
			}
		}
		//若查詢帶等級 
		else
		{
			bool flag=true;
			int k;
			//將許可權名截取出來 
			string temp=qp.substr(0,pos);
			//對使用者的角色進行遍歷
			for(int j=0;j<us[i].num && flag;j++)
			{
				//對角色的所有許可權進行遍歷 
				for(k=0;us[i].a[j].a[k].cat!=temp && k<us[i].a[j].num;k++);
				//若找到了qp許可權 
				if(k!=us[i].a[j].num && us[i].a[j].a[k].level>=qp[qp.length()-1])
				{
					//將他的等級輸出,再將flag置為false表示找到了 
					cout<<"true"<<endl;
					flag=false;
					break;
				}
			}
			//若沒找到則輸出false 
			if(flag)
				cout<<"false"<<endl;
		}
	}
	return 0;
}