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);
}

好难受啊,等分数线,唉,希望如愿吧。无就再来。

 

 

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