2019冬季PAT甲級題解

現在等貴浙的複試分數線,很危險,希望能過。

去年年底考的PAT,運氣好滿分了。一直沒啥心思,最近想起來,決定稍微寫一個題解。

7-1 Good in C (20分)

When your interviewer asks you to write "Hello World" using C, can you do as the following figure shows?

HWC.jpg

Input Specification:

Each input file contains one test case. For each case, the first part gives the 26 capital English letters A-Z, each in a 7×5 matrix of C's and .'s. Then a sentence is given in a line, ended by a return. The sentence is formed by several words (no more than 10 continuous capital English letters each), and the words are separated by any characters other than capital English letters.

It is guaranteed that there is at least one word given.

Output Specification:

For each word, print the matrix form of each of its letters in a line, and the letters must be separated by exactly one column of space. There must be no extra space at the beginning or the end of the word.

Between two adjacent words, there must be a single empty line to separate them. There must be no extra line at the beginning or the end of the output.

Sample Input:

..C..
.C.C.
C...C
CCCCC
C...C
C...C
C...C
CCCC.
C...C
C...C
CCCC.
C...C
C...C
CCCC.
.CCC.
C...C
C....
C....
C....
C...C
.CCC.
CCCC.
C...C
C...C
C...C
C...C
C...C
CCCC.
CCCCC
C....
C....
CCCC.
C....
C....
CCCCC
CCCCC
C....
C....
CCCC.
C....
C....
C....
CCCC.
C...C
C....
C.CCC
C...C
C...C
CCCC.
C...C
C...C
C...C
CCCCC
C...C
C...C
C...C
CCCCC
..C..
..C..
..C..
..C..
..C..
CCCCC
CCCCC
....C
....C
....C
....C
C...C
.CCC.
C...C
C..C.
C.C..
CC...
C.C..
C..C.
C...C
C....
C....
C....
C....
C....
C....
CCCCC
C...C
C...C
CC.CC
C.C.C
C...C
C...C
C...C
C...C
C...C
CC..C
C.C.C
C..CC
C...C
C...C
.CCC.
C...C
C...C
C...C
C...C
C...C
.CCC.
CCCC.
C...C
C...C
CCCC.
C....
C....
C....
.CCC.
C...C
C...C
C...C
C.C.C
C..CC
.CCC.
CCCC.
C...C
CCCC.
CC...
C.C..
C..C.
C...C
.CCC.
C...C
C....
.CCC.
....C
C...C
.CCC.
CCCCC
..C..
..C..
..C..
..C..
..C..
..C..
C...C
C...C
C...C
C...C
C...C
C...C
.CCC.
C...C
C...C
C...C
C...C
C...C
.C.C.
..C..
C...C
C...C
C...C
C.C.C
CC.CC
C...C
C...C
C...C
C...C
.C.C.
..C..
.C.C.
C...C
C...C
C...C
C...C
.C.C.
..C..
..C..
..C..
..C..
CCCCC
....C
...C.
..C..
.C...
C....
CCCCC
HELLO~WORLD!

Sample Output: 

C...C CCCCC C.... C.... .CCC.
C...C C.... C.... C.... C...C
C...C C.... C.... C.... C...C
CCCCC CCCC. C.... C.... C...C
C...C C.... C.... C.... C...C
C...C C.... C.... C.... C...C
C...C CCCCC CCCCC CCCCC .CCC.

C...C .CCC. CCCC. C.... CCCC.
C...C C...C C...C C.... C...C
C...C C...C CCCC. C.... C...C
C.C.C C...C CC... C.... C...C
CC.CC C...C C.C.. C.... C...C
C...C C...C C..C. C.... C...C
C...C .CCC. C...C CCCCC CCCC.

評價: 這題emm,有了9月PAT的經驗,讓我真的不敢小瞧20分的題,一上來整了差不多20多分鐘後還是ac不了,只能拿14分我記得,就是有兩個點卡了,過不去,然後當時看了一下排名,發現大家都是先ac後面的題,於是我也去a後面的題了,在考場上真的要注意。不要死在一道題,9月份的我就是犯了這個錯誤。

思路:首先讀題,其實大致任務就是:輸入字符矩陣-》輸入要輸出的字符串-》輸出結果

那麼就可以分爲三個部分,第一個部分很簡單,將字符矩陣存在26個二位數組就好,也就是一個三維數組。

第二部分輸入要輸出的字符串,這裏對字符串的處理,這裏就要回歸題意:字符串被除了'A'~'Z'以外的字符隔開,然後逐行的輸出。

這裏要注意這句話 “Then a sentence is given in a line, ended by a return.”

這句話告訴我們,空格也要算成是字符串的內容,也就是說我們若用string來存輸入的字符串,得用getline而不是cin

然後就是將字符串的每個字符一個一個遍歷,如果是'A'~'Z',就存到一個待輸出字符串temp裏(將字符串temp初始化爲“”,然後當前遍歷的字符爲大寫字母就temp+=s[i],s爲我們輸入的字符串,s[i]爲當前遍歷到的大寫字母)。每次遇到一個不是大寫字母的,就將這個temp字符串,插入到一個vector內,然後將temp置爲空,再繼續讀取字符串,以此類推。最後得到一個vector vs,vs[i]即爲要輸出的第i行內容。

最後再輸出,輸出的時候,注意題意給的要求,例如空格和換行就可以了。

代碼:

#include <cstdio>
#include <vector>
#include <iostream>
#include <string>
using namespace std;


char keys[8][6][27];

int main()
{
	for(int z=0;z<26;z++)
	{
		for(int x=0;x<7;x++)
		{
			for(int y=0;y<5;y++)
			{
				cin>>keys[x][y][z];
			}
		}
	}
	getchar();
	vector<string> vs;
	string s;
	getline(cin,s);
	int index=0,len=0;
	string temp;
	for(int i=0;i<s.length();i++)
	{
		if(s[i]>='A'&&s[i]<='Z')
		{
			temp+=s[i];
		}
		else
		{
			if(temp!="")
				vs.push_back(temp);
			temp="";
		}
	}
	if(temp!="")
	{
		vs.push_back(temp);
	}
	for(int k=0;k<vs.size();k++)
	{
		for(int x=0;x<7;x++)
		{
			for(int i=0;i<vs[k].length();i++)
			{
				for(int j=0;j<5;j++)
				{
					printf("%c",keys[x][j][vs[k][i]-'A']);
				}
				if(i!=vs[k].length()-1)
					printf(" ");
				else
					printf("\n");
			}
		}
		if(k!=vs.size()-1)
			printf("\n");
	}
 } 

7-2 Block Reversing (25分)

Given a singly linked list L. Let us consider every K nodes as a block (if there are less than K nodes at the end of the list, the rest of the nodes are still considered as a block). Your job is to reverse all the blocks in L. For example, given L as 1→2→3→4→5→6→7→8 and K as 3, your output must be 7→8→4→5→6→1→2→3.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10​5​​) which is the total number of nodes, and a positive K (≤N) which is the size of a block. The address of a node is a 5-digit nonnegative integer, and NULL is represented by −1.

Then N lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node, Data is an integer, and Next is the position of the next node.

Output Specification:

For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

00100 8 3
71120 7 88666
00000 4 99999
00100 1 12309
68237 6 71120
33218 3 00000
99999 5 68237
88666 8 -1
12309 2 33218

Sample Output:

71120 7 88666
88666 8 00000
00000 4 99999
99999 5 68237
68237 6 00100
00100 1 12309
12309 2 33218
33218 3 -1

評價:這個題感覺emm,沒啥好說的,就是送分題,當時考場10多分鐘就一次ac了,非常常規的鏈表題。

思路:一般遇到這種鏈表然後要處理的,一定要先注意,所有的操作,都要先遍歷鏈表,因爲有一些測試點,他會在輸入的時候輸入一些並不存在在鏈表中的節點,所以都要在遍歷了鏈表,然後再對鏈表根據題目進行操作。像這道題,可以藉助棧,來很容易的完成這種翻轉的操作。把鏈表的節點按block(塊)裝入棧,然後再從棧裏面輸出就好了。直接貼代碼了。

代碼:

#include <stack>
#include <vector>
#include <cstdio>
using namespace std;
const int maxn = 100001;

struct Node{
	int id;
	int data;
	int next;
}node[maxn];

int first,n,k;


int main()
{
	scanf("%d%d%d",&first,&n,&k);
	int tempid,tempdata,tempnext;
	for(int i=0;i<n;i++)
	{
		scanf("%d%d%d",&tempid,&tempdata,&tempnext);
		node[tempid].id = tempid;
		node[tempid].data = tempdata;
		node[tempid].next = tempnext;
	}
	vector<int> list;
	stack<vector<int> > s;
	int count=0;
	for(int p = first;p!=-1;p=node[p].next)
	{
		list.push_back(p);
		count++;
		if(count==k)
		{
			s.push(list);
			list.clear();
			count=0;
		}
	}
	if(!list.empty())
	{
		s.push(list);
	}
	vector<int> res,temp;
	while(!s.empty())
	{
		temp = s.top();
		s.pop();
		for(int i=0;i<temp.size();i++)
		{
			res.push_back(temp[i]);
		}
	}
	
	for(int i=0;i<res.size();i++)
	{
		if(i==res.size()-1)
		{
			printf("%05d %d -1",res[i],node[res[i]].data);
		}
		else
		{
			printf("%05d %d %05d\n",res[i],node[res[i]].data,res[i+1]);
		}
	}
	
}

7-3 Summit (25分)

summit (峯會) is a meeting of heads of state or government. Arranging the rest areas for the summit is not a simple job. The ideal arrangement of one area is to invite those heads so that everyone is a direct friend of everyone.

Now given a set of tentative arrangements, your job is to tell the organizers whether or not each area is all set.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (≤ 200), the number of heads in the summit, and M, the number of friendship relations. Then M lines follow, each gives a pair of indices of the heads who are friends to each other. The heads are indexed from 1 to N.

Then there is another positive integer K (≤ 100), and K lines of tentative arrangement of rest areas follow, each first gives a positive number L (≤ N), then followed by a sequence of L distinct indices of the heads. All the numbers in a line are separated by a space.

Output Specification:

For each of the K areas, print in a line your advice in the following format:

  • if in this area everyone is a direct friend of everyone, and no friend is missing (that is, no one else is a direct friend of everyone in this area), print Area X is OK..

  • if in this area everyone is a direct friend of everyone, yet there are some other heads who may also be invited without breaking the ideal arrangement, print Area X may invite more people, such as H. where H is the smallest index of the head who may be invited.

  • if in this area the arrangement is not an ideal one, then print Area X needs help. so the host can provide some special service to help the heads get to know each other.

Here X is the index of an area, starting from 1 to K.

Sample Input:

8 10
5 6
7 8
6 4
3 6
4 5
2 3
8 2
2 7
5 3
3 4
6
4 5 4 3 6
3 2 8 7
2 2 3
1 1
2 4 6
3 3 2 1

Sample Output:

Area 1 is OK.
Area 2 is OK.
Area 3 is OK.
Area 4 is OK.
Area 5 may invite more people, such as 3.
Area 6 needs help.

評價:這道題看上去有點嚇人,怎麼就開會啥的花裏胡哨的,其實慢慢讀,然後慢慢將裏面的內容抽象出來,其實會發現這道題跟PAT題庫裏面的一道題思路可以說是百分之90的相似度。那道題(1142)我還寫過題解。當時在考場靜下心看完就知道了,然後大概也是10多分鐘就ac了。

思路:遇到這種題我是絕對不會搞個二維矩陣就去搞個圖出來的,絕對不可能的。看上去是圖的問題,其實只關注邊和頂點的信息就好了。於是可以用vector a b,a[i] b[i]就表示一條邊的兩個端點,然後接下來就是探索,從每次給的幾個點(提問集),如何判斷出結果。可以通過遍歷每一條邊,再加上使用一個數組來表示遍歷每條邊後,每次的提問集中的點,在邊中都出現的次數,以及每次有提問集中的點出現時,另外一個不在提問集中的點出現的次數。然後就可以判斷出結果。這個用語言有點難以表述,回頭我再補充。不過最好的理解方法,就是拿出筆和紙,然後你自己模擬一下,用兩個數組:一個裝當前邊兩個端點都在提問集的次數,以及在當前邊中只有一個點在提問集,另一個點出現的個數。就可以很輕鬆的發現規律。然後根據這兩個數組,就可以判斷出結果並輸出。

代碼:

#include <cstdio>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 222;
int same[maxn],maybe[maxn];
int n,m,k;
vector<int> a,b;
//int a[101],b[101];
int main()
{
	int g;
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++)
	{
		scanf("%d",&g);
   //     a[i]=g;
    	a.push_back(g);
		scanf("%d",&g);
    //    b[i]=g;
		b.push_back(g);
	}
	scanf("%d",&k);
	int times,temp;
	for(int j=0;j<k;j++)
	{
		fill(same,same+maxn,0);
		fill(maybe,maybe+maxn,0);
		set<int> s;
		scanf("%d",&times);
		for(int i=0;i<times;i++)
		{
			scanf("%d",&temp);
			s.insert(temp);
		}
		for(int i=0;i<m;i++)
		{
			if(s.count(a[i])!=0&&s.count(b[i])!=0)
			{
				same[a[i]]++;
				same[b[i]]++;
			}
			else if(s.count(a[i])!=0||s.count(b[i])!=0)
			{
				if(s.count(a[i])!=0)
				{
					maybe[b[i]]++;
				}
				else
				{
					maybe[a[i]]++;
				}
			}
		}
		int res=1;
		for(auto it:s)
		{
			if(same[it]!=times-1)
			{
				res = 3;
				break;
			}
		}
		if(res==3)
		{
			printf("Not a Clique\n");
		}
		else
		{
			for(int i=1;i<=n;i++)
			{
				if(maybe[i]==times)
				{
					res=2;
					break;
				}
			}
		}
		if(res==1)
		{
			printf("Yes\n");
		}
		else if(res==2)
		{
			printf("Not Maximal\n");
		}
	}
}

7-4 Cartesian Tree (30分)

Cartesian tree is a binary tree constructed from a sequence of distinct numbers. The tree is heap-ordered, and an inorder traversal returns the original sequence. For example, given the sequence { 8, 15, 3, 4, 1, 5, 12, 10, 18, 6 }, the min-heap Cartesian tree is shown by the figure.

CTree.jpg

Your job is to output the level-order traversal sequence of the min-heap Cartesian tree.

Input Specification:

Each input file contains one test case. Each case starts from giving a positive integer N (≤30), and then N distinct numbers in the next line, separated by a space. All the numbers are in the range of int.

Output Specification:

For each test case, print in a line the level-order traversal sequence of the min-heap Cartesian tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

10
8 15 3 4 1 5 12 10 18 6

Sample Output:

1 3 5 8 4 6 15 10 12 18

 評價:當時昨晚兩道25的題目,還有第一題拿了14分,用了將近1個小時的時間,心裏想着如果這道題能寫出來就90分了,結果一看題意,看到heap這個單詞,心想,完了當時考前很偷懶就沒有複習heap的模板,但是緊張過後一看,媽的這玩意又不是完全二叉樹,heap個錘子。所以就開心,然後看了一下,發現很簡單,只要模仿根據前中序序列生成二叉樹的模板,寫出一個遞歸將二叉樹構造出來就可以了。

思路:

 例如根據前序序列和中序序列轉換成二叉樹。每次我們選擇的節點,是根據前序序列來選擇,在這道題,只要將這個條件改成根據數據的大小來選擇當前插入的點就好,即每次都選擇區間內最小的點插入。最好還是根據代碼理解。

代碼:

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int INF = 0x3fffffff;
struct Node{
	int data;
	Node* left;
	Node* right;
};
int n;

vector<int> in;

int countt=0;

Node* create(int inl,int inr)
{
	if(inl>inr)
	{
		return NULL;
	}
	int u,minn=INF;
	for(int i=inl;i<=inr;i++)
	{
		if(minn>in[i])
		{
			u=i;
			minn=in[i];
		}
	}
	Node* root = new Node;
	root->data = minn;
	root->left = create(inl,u-1);
	root->right = create(u+1,inr);
	return root;
}

void bfs(Node* root)
{
	int num=0;
	queue<Node*> q;
	q.push(root);
	while(!q.empty())
	{
		Node* top = q.front();
		q.pop();
		printf("%d",top->data);
		num++;
		if(num<n)
			printf(" ");
		if(top->left!=NULL)
		{
			q.push(top->left);
		}
		if(top->right!=NULL)
		{
			q.push(top->right);
		}
	}
}

int main()
{
	int temp;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&temp);
		in.push_back(temp);
	}
	Node* root=create(0,n-1);
	bfs(root);
}

好難受啊,等分數線,唉,希望如願吧。無就再來。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章