阅读原文
当时准备 PAT 竞赛时候,买了本《算法笔记》,书中将题型进行分类,是我最系统的一次算法学习,对题型判断、解题思路都有了新的认知,本篇文章主要记录当时刷的入门模拟题,算是比较简单的算法题(有些都不能称之为算法),就当是打基础了
包括分类:简单模拟、查找元素、图形输出、日期处理、进制转换、字符串处理
根据题目的要求去做即可,主要考察代码的编写能力
题目:Shuffling Machine
Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techniques are seen as weak, and in order to avoid “inside jobs” where employees collaborate with gamblers by performing inadequate shuffles, many casinos employ automatic shuffling machines. Your task is to simulate a shuffling machine.
The machine shuffles a deck of 54 cards according to a given random order and repeats for a given number of times. It is assumed that the initial status of a card deck is in the following order:
S1, S2, …, S13, H1, H2, …, H13, C1, C2, …, C13, D1, D2, …, D13, J1, J2
where “S” stands for “Spade”, “H” for “Heart”, “C” for “Club”, “D” for “Diamond”, and “J” for “Joker”. A given order is a permutation of distinct integers in [1, 54]. If the number at the i-th position is j, it means to move the card from position i to position j. For example, suppose we only have 5 cards: S3, H5, C1, D13 and J2. Given a shuffling order {4, 2, 5, 3, 1}, the result will be: J2, H5, D13, S3, C1. If we are to repeat the shuffling again, the result will be: C1, H5, S3, J2, D13.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer K (<= 20) which is the number of repeat times. Then the next line contains the given order. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the shuffling results in one line. All the cards are separated by a space, and there must be no extra space at the end of the line.
Sample Input:
2
36 52 37 38 3 39 40 53 54 41 11 12 13 42 43 44 2 4 23 24 25 26 27 6 7 8 48 49 50 51 9 10 14 15 16 5 17 18 19 1 20 21 22 28 29 30 31 32 33 34 35 45 46 47
Sample Output:
S7 C11 C10 C12 S1 H7 H8 H9 D8 D9 S11 S12 S13 D10 D11 D12 S3 S4 S6 S10 H1 H2 C13 D2 D3 D4 H6 H3 D13 J1 J2 C1 C2 C3 C4 D1 S5 H5 H11 H12 C6 C7 C8 C9 S2 S8 S9 H10 D5 D6 D7 H4 H13 C5
思路: 用字符串不如使用整型数组直接进行循环调换,根据其编号输出对应的花色
建立三个整型数组,分别用来存储初始顺序、洗牌后的顺序、洗牌规则
每次洗牌就是将规则数组中的当前数字作为下标用来控制洗牌后的数组被赋值洗牌前的编号
最后花色和数值的输出需要对编号进行-1,这样是为了防止 13、26…这样的边界数字越界的情况,但输出数值时需要再+1
代码:
#include
int main()
{
int times;
scanf("%d", ×); //输入洗牌几次
int start[55], end[55], order[55];
for (int i = 1; i < 55; i++)
{
scanf("%d", &order[i]); //输入洗牌规则
start[i] = i; //初始化默认排序
}
for (int i = 0; i < times; i++)
{
for (int j = 1; j < 55; j++)
{
end[order[j]] = start[j]; //根据规则洗牌
}
for (int k = 1; k < 55; k++)
{
start[k] = end[k]; //将每次洗完的牌放到初始数组,为下一次洗牌做准备
}
}
char color[5] = {'S', 'H', 'C', 'D', 'J'}; //字符花色数组
for (int i = 1; i < 55; i++)
{
end[i]--;
//每次的序号都要自减,防止 13、26…这样的数字除和摸出 13 时得到的值不符合逻辑
printf("%c%d", color[end[i] / 13], end[i] % 13 + 1);
if (i != 54)
{ //避免额外空格
printf(" ");
}
}
return 0;
}
题目:Shortest Distance
The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.
Input Specification:
Each input file contains one test case. For each case, the first line contains an integer N (in [3, 1 0 5 10^5 105]), followed by N integer distances D1 D2 ⋯ DN, where Di is the distance between the i-th and the (i+1)-st exits, and DN is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (≤ 1 0 4 10^4 104), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than 1 0 7 10^7 107.
Output Specification:
For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.
Sample Input:
5 1 2 4 14 9
3
1 3
2 5
4 1
Sample Output:
3
10
7
思路: 实际上只有一条循环线路,只要求出单个方向(如顺时针)的值,用距离总和减去后获得反向距离,返回二者最小值
创建一个距离数组distance[]
,其中distance[i]
中保存的是从 V1 点到 Vi+1 的距离,在输入时就将数组和距离总和记录下来减少复杂度
输入的起点 begin 和终点 end 之间的顺时针距离 dis_left 为 dis_left=distance[end-1]-distance[begin-1]
,需要判断 begin 与 end 的大小关系,始终保持小的在前
代码:
#include
#include
using namespace std;
int main()
{
int n;
scanf("%d", &n);
vector dis(n + 1); //动态数组分配空间后所有的值为 0
int sum = 0, left, right;
for (int i = 1; i <= n; i++)
{
int temp;
scanf("%d", &temp);
sum += temp;
dis[i] = sum; //距离数组保存的是 V1 到 Vi 的顺时针距离
}
int cnt;
scanf("%d", &cnt); //输入判断几对
for (int i = 0; i < cnt; i++)
{
scanf("%d %d", &left, &right);
if (left > right) //始终保持顺时针判断
swap(left, right);
int temp = dis[right - 1] - dis[left - 1];
printf("%d\n", min(temp, sum - temp));
}
system("pause");
return 0;
}
题目:A+B and C (64bit)
Given three integers A, B and C in [− 2 63 2^{63} 263, 2 63 2^{63} 263),you are supposed to tell whether A+B>C.
Input Specification:
The first line of the input gives the positive number of test cases, T (≤10). Then T test cases follow, each consists of a single line containing three integers A, B and C, separated by single spaces.
Output Specification:
For each test case, output in one line Case #X: true
if A+B>C, or Case #X: false
otherwise, where X is the case number (starting from 1).
Sample Input:
3
1 2 3
2 3 4
9223372036854775807 -9223372036854775808 0
Sample Output:
Case #1: false
Case #2: true
Case #3: false
思路: 数据类型过大用 long long
型进行存储,同时需要考虑溢出的情况(同为正值溢出必大于,同为负值溢出必小于)
因为 A、B 的大小为 [-2^63, 2^63),用 long long 存储 A 和 B 的值,以及他们相加的值 sum
如果 A > 0, B < 0 或者 A < 0, B > 0,sum 是不可能溢出的
如果 A > 0, B > 0,sum 可能会溢出,sum 范围理应为 (0, 2^64 – 2],溢出得到的结果应该是 [-2^63, -2] 是个负数,所以 sum < 0 时候说明溢出了
如果 A < 0, B < 0,sum 可能会溢出,同理,sum 溢出后结果是大于 0 的,所以 sum > 0 说明溢出了
代码:
#include
#include
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
long long a, b, c;
scanf("%lld %lld %lld", &a, &b, &c);
long long sum = a + b;
if (a > 0 && b > 0 && sum < 0)
{ //正溢出,结果必定大于 C
printf("Case #%d: true\n", i + 1);
}
else if (a < 0 && b < 0 && sum >= 0)
{ //负溢出,两个负数相加而且溢出,必小于 C
printf("Case #%d: false\n", i + 1);
}
else if (sum > c) //无溢出,正常比较
{
printf("Case #%d: true\n", i + 1);
}
else
{
printf("Case #%d: false\n", i + 1);
}
}
system("pause");
return 0;
}
题目:A+B for Polynomials
This time, you are supposed to find A+B where A and B are two polynomials.
Input Specification:
Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:
K N1 aN1 N2 aN2 … NK aNK
where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1,2,⋯,K) are the exponents and coefficients, respectively. It is given that 1≤K≤10,0≤NK<⋯< N2 Output Specification: For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place. Sample Input: 2 1 2.4 0 3.2 Sample Output: 3 2 1.5 1 2.9 0 3.2 思路: 使用浮点数组用指数作为下标,存储系数的值,只要指数相同就为同一项,系数直接相加即可 数组长度为指数的最大值 1000, 注意输出格式和输出的精度 代码: 题目:Product of Polynomials This time, you are supposed to find A×B where A and B are two polynomials. Input Specification: Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N1 aN1 N2 aN2 … NK aNK where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1, 2, ⋯, K) are the exponents and coefficients, respectively. It is given that 1≤K≤10, 0≤NK<⋯ Output Specification: For each test case you should output the product of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate up to 1 decimal place. Sample Input: 2 1 2.4 0 3.2 Sample Output: 3 3 3.6 2 6.0 1 1.6 思路: 建立两个数组,一个保存第一行的多项式,一个在第二行读入时,直接循环第一个数组的内容进行处理存储 因为是乘法,根据最大指数为 1000,那么乘积的最大指数就是 2000,所以 ans 数组的数据规模为 2001 无需将两个多项式分别保存完再处理,在输入第二个多项式时直接循环与第一个多项式的每一项相乘即可(只算非零) 代码: 在一组给定的元素中查找目标元素,范围较小可直接遍历查找,或者使用某些数据类型自带的 find() 函数,查找最大最小值可以使用 [algorithm] 下的 max_elemen() 函数等 有些元素的数据范围较大,采用遍历消耗的时间难免过多,所以采用二分查找的方式能够用较小的时间复杂度来完成 具体思路就是每次确定中值 题目:World Cup Betting With the 2010 FIFA World Cup running, football fans the world over were becoming increasingly excited as the best players from the best teams doing battles for the World Cup trophy in South Africa. Similarly, football betting fans were putting their money where their mouths were, by laying all manner of World Cup bets. Chinese Football Lottery provided a “Triple Winning” game. The rule of winning was simple: first select any three of th
2 2 1.5 1 0.5
poly[i] = j
表示指数 i 的系数为 j,接收 exponent 和 coefficient 输入的同时将对应指数的系数加入到 poly 数组中,所有非零系数的个数,然后从前往后输出所有系数不为 0 的指数和系数#include
1009
2 2 1.5 1 0.5
#include
查找元素
思想解释
二分查找
mid=(left+right)/2
,用要查询的数 x 与 mid 进行比较,根据大小关系再与另一半进行比较,值得注意的是,有些数据范围实在是太大导致 left+right 的值就已经超过的 int 支持的数据范围,这时可以使用mid=left+(right-left)/2
在 [algorithm] 下的模板函数为:binary_search(first,last,val)
类型练习
1011