1049. Counting Ones (30)-PAT甲级真题(数学问题)

The task is simple: given any positive integer N, you are supposed to count the total number of 1’s in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1’s in 1, 10, 11, and 12.

Input Specification:

Each input file contains one test case which gives the positive N (<=230).

Output Specification:

For each test case, print the number of 1’s in one line.

Sample Input:
12
Sample Output:
5
题目大意:给出一个数字n,求1~n的所有数字里面出现1的个数
分析:这是一道数学问题。从第一位(个位)到最高位,设now为当前位的数字,left为now左边的所有数字构成的数字,right是now右边的所有数字构成的数字。只需要一次次累加对于当前位now来说可能出现1的个数,然后把它们累加即可。a表示当前的个位为1,十位为10,百位为100类推。
对于now,有三种情况:
1.now == 0 : 那么 ans += left * a; //因为now==0说明now位只有在left从0~left-1的时候会产生1,所以会产生left次,但是又因为右边会重复从0~999…出现a次
2.now == 1 : ans += left * a + right + 1;//now = 1的时候就要比上一步多加一个当now为1的时候右边出现0~right个数导致的now为1的次数
3.now >= 2 : ans += (left + 1) * a;//now大于等于2就左边0~left的时候会在now位置产生1,所以会产生left次,但是又因为右边会重复从0~999…出现a次

 

1038. Recover the Smallest Number (30)-PAT甲级真题(贪心算法)

Given a collection of number segments, you are supposed to recover the smallest number from them. For example, given {32, 321, 3214, 0229, 87}, we can recover many numbers such like 32-321-3214-0229-87 or 0229-32-87-321-3214 with respect to different orders of combinations of these segments, and the smallest number is 0229-321-3214-32-87.

Input Specification:

Each input file contains one test case. Each case gives a positive integer N (<=10000) followed by N number segments. Each segment contains a non-negative integer of no more than 8 digits. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the smallest number in one line. Do not output leading zeros.

Sample Input:
5 32 321 3214 0229 87
Sample Output:
22932132143287
题目大意:给一些字符串,求它们拼接起来构成最小数字的方式
分析:贪心算法。让我们一起来见证cmp函数的强大之处!!~~不是按照字典序排列就可以的,必须保证两个字符串构成的数字是最小的才行,所以cmp函数写成return a + b < b + a;的形式,保证它排列按照能够组成的最小数字的形式排列。
因为字符串可能前面有0,这些要移除掉(用s.erase(s.begin())就可以了~嗯~string如此神奇~~)。输出拼接后的字符串即可。
注意:如果移出了0之后发现s.length() == 0了,说明这个数是0,那么要特别地输出这个0,否则会什么都不输出~

 

1067. Sort with Swap(0,*) (25)-PAT甲级真题(贪心算法)

Given any permutation of the numbers {0, 1, 2,…, N-1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:
Swap(0, 1) => {4, 1, 2, 0, 3}
Swap(0, 3) => {4, 1, 2, 3, 0}
Swap(0, 4) => {0, 1, 2, 3, 4}
Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.
Input Specification:
Each input file contains one test case, which gives a positive N (<=105) followed by a permutation sequence of {0, 1, …, N-1}. All the numbers in a line are separated by a space.
Output Specification:
For each case, simply print in a line the minimum number of swaps need to sort the given permutation.

Sample Input:
10 3 5 7 2 6 4 9 0 8 1
Sample Output:
9
题目大意:给出一个n个数的序列,数字为0~n-1的乱序,每次用两两交换的方式而且只能用0和另一个数交换,使序列变成有序的,问最少需要多少步骤。
分析:1.0号为哨兵, 用哨兵与其他数字交换,使其他数字回到有序的位置(最后有序时所处的位置),则排序完成
2.a[t] = i; 表示t数字当前正在占着哪一个位置。 (如果想实时监测每个数字的位置,可以用 b 数组{b[a[i]] = i } 缓存一下数据,输出查看的)
3.依次遍历每个位置i,如果当前位置不是与之对应的数字,那么我们让这哨兵来去该数执行操作回到正确位置
4.数字如何被哨兵执行操作回到序的位置:
如果哨兵此时不在自己有序的位置上,那就,先让哨兵去让他占的那个位置上的真正应该放的数字回到此位置,即交换哨兵和此数字,我们swap(a[0],a[a0]),直到哨兵在交换的过程中回到了自己的有序位置。字词再次检查该位置是不是应该放的数字(别的数字回到有序位置的时候即哨兵执行操作的过程中,有可能让此位置该有的数字回到位置)。如果此位置不是当前数字,那哨兵和他交换swap(a[0],a[i]),就是让他先去哨兵的有序位置待一会,等下一轮操作,哨兵会把他交换回来的。如果此位置已经是该数字了,那就什么都不做。
5.当到达最后一个位置时候,两种情况 1)。如果第一个数字和最后一个数字都在自己的有序位置 那ok~ 2).哨兵和最后一个数字互相占着对方的位置,那最后一个数字就是哨兵,交换一次后,哨兵在交换后的位置等待,就是已经回到自己的有序位置,此时排序也是完成的。此过程包括在4里面了,怕你们不理解,单独说一下~

1113. Integer Set Partition (25)-PAT甲级真题

Given a set of N (> 1) positive integers, you are supposed to partition them into two disjoint sets A1 and A2 of n1 and n2 numbers, respectively. Let S1 and S2 denote the sums of all the numbers in A1 and A2, respectively. You are supposed to make the partition so that |n1 – n2| is minimized first, and then |S1 – S2| is maximized.

Input Specification:

Each input file contains one test case. For each case, the first line gives an integer N (2 <= N <= 105), and then N positive integers follow in the next line, separated by spaces. It is guaranteed that all the integers and their sum are less than 231.

Output Specification:

For each case, print in a line two numbers: |n1 – n2| and |S1 – S2|, separated by exactly one space.

Sample Input 1:
10
23 8 10 99 46 2333 46 1 666 555
Sample Output 1:
0 3611
Sample Input 2:
13
110 79 218 69 3721 100 29 135 2 6 13 5188 85
Sample Output 2:
1 9359

题目大意:要求把一个集合分成两个不相交的集合,使得这两个集合的元素个数相差最小的前提下,两个集合的总和之差最大
分析:先把集合内n个元素排序,计算前n/2个元素的总和,然后用总的总和sum – 2 * halfsum即为 |S1 – S2|。
|n1 – n2|就是n % 2的结果,奇数为1,偶数为0。(总和sum的值其实可以在输入的时候就累加得到啦~)

 

1078. Hashing (25)-PAT甲级真题(二次方探查法)

The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers. The hash function is defined to be “H(key) = key % TSize” where TSize is the maximum size of the hash table. Quadratic probing (with positive increments only) is used to solve the collisions.

Note that the table size is better to be prime. If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers: MSize (<=104) and N (<=MSize) which are the user-defined table size and the number of input numbers, respectively. Then N distinct positive integers are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the corresponding positions (index starts from 0) of the input numbers in one line. All the numbers in a line are separated by a space, and there must be no extra space at the end of the line. In case it is impossible to insert the number, print “-” instead.

Sample Input:
4 4
10 6 4 15
Sample Output:
0 1 4 –

题目大意:给出散列表长和要插入的元素,将这些元素按照读入的顺序插入散列表中,其中散列函数为h(key) = key % TSize,解决冲突采用只向正向增加的二次方探查法。如果题中给出的TSize不是素数,就取第一个比TSize大的素数作为TSize
分析:先解决size是否为素数,不是素数就要重新赋值的问题
然后根据二次方探查法:
– 如果hashTable里面key % size的下标对应的hashTable为false,说明这个下标没有被使用过,直接输出。否则step步长从1加到size-1,一次次尝试是否能使index = (key + step * step) % size;所对应的位置没有元素,如果都没有找到就输出“-”,否则就输出这个找到的元素的位置~
– 注意 是(key + step * step) % size 而不是(key % size + step * step) 

 

1022. Digital Library (30)-PAT甲级真题(map映射)

A Digital Library contains millions of books, stored according to their titles, authors, key words of their abstracts, publishers, and published years. Each book is assigned an unique 7-digit number as its ID. Given any query from a reader, you are supposed to output the resulting books, sorted in increasing order of their ID’s.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the total number of books. Then N blocks follow, each contains the information of a book in 6 lines:

Line #1: the 7-digit ID number;
Line #2: the book title — a string of no more than 80 characters;
Line #3: the author — a string of no more than 80 characters;
Line #4: the key words — each word is a string of no more than 10 characters without any white space, and the keywords are separated by exactly one space;
Line #5: the publisher — a string of no more than 80 characters;
Line #6: the published year — a 4-digit number which is in the range [1000, 3000].
It is assumed that each book belongs to one author only, and contains no more than 5 key words; there are no more than 1000 distinct key words in total; and there are no more than 1000 distinct publishers.

After the book information, there is a line containing a positive integer M (<=1000) which is the number of user’s search queries. Then M lines follow, each in one of the formats shown below:

1: a book title
2: name of an author
3: a key word
4: name of a publisher
5: a 4-digit number representing the year
Output Specification:

For each query, first print the original query in a line, then output the resulting book ID’s in increasing order, each occupying a line. If no book is found, print “Not Found” instead.

Sample Input:
3
1111111
The Testing Book
Yue Chen
test code debug sort keywords
ZUCS Print
2011
3333333
Another Testing Book
Yue Chen
test code sort keywords
ZUCS Print2
2012
2222222
The Testing Book
CYLL
keywords debug book
ZUCS Print2
2011
6
1: The Testing Book
2: Yue Chen
3: keywords
4: ZUCS Print
5: 2011
3: blablabla
Sample Output:
1: The Testing Book
1111111
2222222
2: Yue Chen
1111111
3333333
3: keywords
1111111
2222222
3333333
4: ZUCS Print
1111111
5: 2011
1111111
2222222
3: blablabla
Not Found

题目大意:模拟数字图书馆的查询功能。会给出n本书的信息,以及m个需要查询的命令,数字标号对应相应的命令,数字编号后面的字符串是查询的搜索词,要求输出这行命令以及输出满足条件的书的id,如果一个都没有找到,输出Not Found

分析:1、对除了id之外的其他信息都建立一个map<string, set>,把相应的id插入对应搜索词的map的集合里面,形成一个信息对应一个集合,集合里面是复合条件的书的id

2、因为对于输入的关键词(可以重复,算是书本对应的tag标签吧~)没有给定关键词的个数,可以使用while(cin >> s)并且判断c = getchar(),c是否等于\n,如果是再退出循环~

3、建立query,通过传参的形式可以将不同的map名称统一化,先要判断map.find()和m.end()是否相等,如果不等再去遍历整个map,输出所有满足条件的id,如果相等就说明不存在这个搜索词对应的id,那么就要输出Not Found~

4、传参一定要用引用,否则最后一组数据可能会超时