4.1 排序

4.1.1 选择排序

void selectSort(int A[], int n) {for (int i = 0; i < n; i++) {int k = i;for (int j = i + 1; j < n; j ++) {if (A[j] < A[k]) {k = j;}}if (k != i) {int temp = A[i];A[i] = A[k];A[k] = temp;}}
}

4.1.2 插入排序

void insertSort(int A[], int n) {for (int i = 1; i < n; i ++) {int temp = A[i], j = i;while (j > 0 && A[j-1] > temp) {A[j] = A[j-1];j--;}A[j] = temp;}
}

4.1.3 排序题的应用

struct Student {char name[10];//名字char id[10];//学号int score;//分数int r;//排名
}stu[10000];//cmp函数的编写
bool cmp(Student a, Student b) {if (a.score != b.score) return a.score > b.score;else return strcmp(a.name, b.name) < 0;
}//排名的实现。相同分数排名相同
//先将数组第一个个体排名记为1,然后遍历剩余个体,
//如果分数等于上一个个体的分数,则排名和上一个个体相同,否则排名等于下标+1stu[0].r = 1;
for (int i = 1; i < n; i++) {if(stu[i].score == stu[i-1].score) {stu[i].r = stu[i-1].r;} else {stu[i].r = i + 1;}
}

【PAT A1025】PAT Ranking

Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhejiang University. Each test is supposed to run simultaneously in several places, and the ranklists will be merged immediately after the test. Now it is your job to write a program to correctly merge all the ranklists and generate the final rank.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive number N (≤100), the number of test locations. Then N ranklists follow, each starts with a line containing a positive integer K (≤300), the number of testees, and then K lines containing the registration number (a 13-digit number) and the total score of each testee. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first print in one line the total number of testees. Then print the final ranklist in the following format:

registration_number final_rank location_number local_rank

The locations are numbered from 1 to N. The output must be sorted in nondecreasing order of the final ranks. The testees with the same score must have the same rank, and the output must be sorted in nondecreasing order of their registration numbers.

Sample Input:

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85
结尾无空行

Sample Output:

9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4
结尾无空行

题意:n个考场,每个考场若干考生,给出的是考生的准考证号和分数,要求按照所有考生分数从高到低排序,按照顺序输出所有考生的准考证号,排名,考场号和考场内排名

思路:结构体Student包含题目要求的所有信息(准考证号,分数,总排名,考场号和考场内排名),需要写一个排序函数cmp。规则如下:

分数不同时,按照分数大小排序

分数相同时,按照准考证号大小排序

算法本体:

  1. 按考场读入考生信息,并对当前读入考场的所有考生进行排序,获得考场内考生排名
  2. 对所有考生进行排序
  3. 按顺序一边计算总排名,一边输出考生信息
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
struct student {long long int no;int score, finrank, loca, locarank;
};
bool cmp1(student a, student b) {return a.score != b.score ? a.score > b.score : a.no < b.no;
}
int main() {int n, m;scanf("%d", &n);vector<student> fin;for(int i = 1; i <= n; i++) {scanf("%d", &m);vector<student> v(m);for(int j = 0; j < m; j++) {scanf("%lld %d", &v[j].no, &v[j].score);v[j].loca = i;}sort(v.begin(), v.end(), cmp1);v[0].locarank = 1;fin.push_back(v[0]);for(int j = 1; j < m; j++) {v[j].locarank = (v[j].score == v[j - 1].score) ? (v[j - 1].locarank) : (j + 1);fin.push_back(v[j]);}}sort(fin.begin(), fin.end(), cmp1);fin[0].finrank = 1;for(int j = 1; j < fin.size(); j++)fin[j].finrank = (fin[j].score == fin[j - 1].score) ? (fin[j - 1].finrank) : (j + 1);printf("%d\n", fin.size());for(int i = 0; i < fin.size(); i++)printf("%013lld %d %d %d\n", fin[i].no, fin[i].finrank, fin[i].loca, fin[i].locarank);return 0;
}

4.2 散列

4.2.1 散列定义

直接把输入的数作为数组下标来对这个数的性质进行统计。即用空间换时间,它将查询的复杂度降到了O(1)级别。

散列:将元素通过一个函数转换为整数,使得该整数可以尽量唯一的代表这个元素。

常用的散列函数为直接定址法、平方取中法、除留余数法等等。

解决冲突的方法有:线性探测法、平方探测法、拉链法

4.2.2 字符串hash初步

将字符串的字母转换为数字表示,比如A-Z用0-25表示,a-z用26-51表示。这样便可以将字符串映射为数字。

int hashFunc(char S[], int len) {int id = 0;for (int i = 0; i < len; i++) {if (S[i] >= 'A' && S[i] <= 'Z') {id = id * 52 + (S[i] - 'A');} else if (S[i] >= 'a' && S[i] <= 'z') {id = id * 52 + (S[i] - 'a');}}return id;
}

如果出现了数字,一般两种处理方法:

①增大进制数至62

②如果保证字符串末尾是确定个数的数字,可以将前面英文字母部分变为数字,然后将末尾的数字拼接上去。如对BCD4,可以将BCD转换为731,然后拼上4就变为7314。

4.3 递归

4.3.1 Fibonaccishulie 数列

int F(int n) {if (n == 0 || n == 1) return 1;else return F(n-1) + F(n-2);
}

4.3.2 全排列

设定一个数组P,用来存放当前的排列;再设定一个散列数组hashTable,其中hashTable[x]当整数x已经在数组P时为true。

现在按顺序往P的第1位到第n位中填入数字。不妨假设当前已经填好了P[1]~P[index-1],正准备填P[index]。显然需要枚举1~n。如果当前的数字x还没有在P[1]~P[index-1]中,则将它填入P[index]中,同时设置hashTable[x]为true。然后去处理P的index+1位,当递归完成时,将hashTable[x]还原为false,以便让P[index]填下一个数字。

#include<stdio.h>
const int maxn = 11;int n, P[maxn], hashTable[maxn] = {false};//当前处理排列的第index位
void generateP(int index) {if (index == n + 1) { //递归边界for (int i = 1; i <= n; i++) {printf("%d",P[i]);}}for (int x = 1; x <= n; x ++) { //枚举1~n,试图将x写到P[index]中if (hashTable[x] == false) {P[index] = x;hashTable[x] = true;generateP(index + 1);hashTable[x] = false;}}
}int main() {n = 3;//1~3的全排列generateP(1);return 0;
}

4.3.3 n皇后问题

void generateP(int index) {if(index == n + 1) {count ++;return ;}for (int x = 1; x <=n ; x++) {//第x行if (hashTable[x] == false) {bool flag = true;for (int pre = 1; pre < index; pre ++) {if (abs(index - pre) == abs(x - P[pre])) {flag = false;//冲突,剪枝break;}}if(flag) {P[index] = x;hashTable[x] = true;generateP(index + 1);hashTable[x] = false;}}
}

4.4 贪心

4.4.1 简单贪心

单价最高

4.4.2 区间贪心

区间不相交问题:将所有开区间左端点从大到小进行排序,左端点相同的按右端点从小到大排序,每次总是选择左端点最大的区间(总是选择右端点最小的区间也是可以的)

#include<stdio.h>
#include<algorthim>
using namespace std;
const int maxn = 110;
struct Inteval {int x, y;
} I[maxn];bool cmp(Inteval a, Inteval b) {if (a.x != b.x) return a.x > b.x;else return a.y < b.y;
}int main() {int n;while(scanf("%d", &n), n !=0) {for (int i = 0; i < n; i ++) {scanf("%d%d",&I[i].x,&I[i].y);}sort(I,I+n,cmp);int ans = 1, lastX = I[0].x;for (int i = 1; i < n; i ++) {if(I[i].y <= lastX) {lastX = I[i].x;ans ++;}}printf("%d\n",ans);
}

如果对于区间选点问题:给出N个闭区间[x,y],求最少需要确定多少个点,才能使得闭区间中都至少存在一个点。

只需要将‘I[i].y <= lastX’改为‘I[i].y <  lastX’

4.5 二分

4.5.1 二分查找

//找出递增序列中第一个大于等于x的下标
int binarySearch(int A[], int left, int right, int x) {int mid;while (left <= right) {//这里是小于等于mid = (left + right) / 2;if (A[mid] == x) return mid;    else if(A[mid] > x) right = mid - 1;else left = mid + 1;}return -1;
}

二分的变形:找出递增序列中第一个大于等于x的元素的位置L以及第一个大于x的元素的位置R,这样元素x在序列中的存在区间就是左闭右开区间[L,R]

①A[mid] >= x,则第一个大于等于x的元素一定在mid处或者mid的左侧,则让right=mid

②A[mid] < x,则第一个大于等于x的元素一定在mid右侧处,则让left = mid + 1

//找出递增序列中第一个大于等于x的下标
int lower_bound(int A[], int left, int right, int x) {int mid;while (left < right) {mid = (left + right) / 2;if (A[mid] >= x) {right = mid;} else {left = mid + 1;}}return left;
}

①A[mid] > x,则第一个大于x的元素一定在mid处或者mid的左侧处,让right = mid

②A[mid] <= x,则第一个大于等于x的元素一定在mid右侧处,让left = mid + 1

//找出递增序列中第一个大于x的下标
int lower_bound(int A[], int left, int right, int x) {int mid;while (left < right) {mid = (left + right) / 2;if (A[mid] > x) {right = mid;} else {left = mid + 1;}}return left;
}

4.5.3 快速幂

算法笔记.胡凡 第四章 算法初步相关推荐

  1. 算法笔记.胡凡 第五章 数学问题

    5.1 简单数学 [PAT A1069] For any 4-digit integer except the ones with all the digits being the same, if ...

  2. 算法笔记胡凡 第3章 入门篇

    3.5进制转换 P进制的数转换为Q进制的数,分为两步: ①将P进制的数x转换为十进制数y ②将十进制数y转换为Q进制数z 除基取余法 [PAT B1022] D进制的A+B 输入两个非负 10 进制整 ...

  3. 算法笔记.胡凡 第11章 动态规划专题

    11.1 动态规划的递归写法和递推写法 11.1.1 动态规划的递归写法 以斐波那契数列为例,递归代码为 int F(int n) {if (n == 0 || n == 1) return 1;el ...

  4. 算法笔记.胡凡 第6章 C++标准模板库(STL)介绍

    6.1 vector常见用法详解 6.1.1.vector定义 vector<int> name; 6.1.2.vector容器元素访问 (1) 下标:v[0] (2)迭代器 vector ...

  5. 算法笔记.胡凡 第九章 二叉树

    9.1 树与二叉树 二叉树的存储 struct node {typename data;node* lchild;node* rchild; }; 新建节点 node* newNode(int v) ...

  6. 算法笔记 胡凡 codeup 数列

    数列 题目链接:http://codeup.cn/problem.php?cid=100000583&pid=1 思路 由于该章节用的是递归,所以就采用递归方式来写而不是动态规划 这样的重复度 ...

  7. 算法笔记 胡凡 codeup 吃糖果

    吃糖果 题目链接:http://codeup.cn/problem.php?cid=100000583&pid=0 思路 就是简单的递归 两种方法:当n只糖果时,可以分为 吃一只糖果,剩下n- ...

  8. 算法笔记胡凡 7.3.4 连接各点时代码有误

    在此书7.3.4中, 静态链表结点定义如下: struct Node{typename data;int next; }node[size]; 书中要将11111,22222,33333三个地方的节点 ...

  9. 《算法笔记--胡凡,曾磊主编》set的用法

    set的用法 set 翻译为集合,是一个内部有序且不重复的容器 #include<set> using namespace std;set的定义 定义一个set : set<type ...

最新文章

  1. ajax php计数,jQuery+PHP+Ajax动态数字统计展示实例
  2. getjsonobject字符串解析出错_【干货分享】达梦DISQL工具使用解析之 DISQL环境变量设置...
  3. ImportError: No module named Cython.Build
  4. 互联网账户系统的具体实现
  5. ASP面向对象编程探讨及比较
  6. shiro使用WebService进行验证的实现
  7. Java面试通关要点汇总整理
  8. uwp - ContentDialog - 自定义仿iphone提示框,提示框美化
  9. Blog从Hexo迁移至Wordpress
  10. MAC:使用install_name_rpath修改编译结果的rpath
  11. 高等代数——大学高等代数课程创新教材(丘维声)——2.3笔记+习题
  12. 【VS插件】VS2012设置透明背景
  13. php7和PHP5对比的新特性和性能优化
  14. 【Linux私房菜】第四期——管理
  15. 下载Postman并且汉化使用
  16. oracle group by优化
  17. 并行是什么意思?与并发的区别是什么?
  18. 什么是AUTOSAR, 为什么要用AUTOSAR
  19. ELK - docker
  20. expdp和impdp备份数据库(数据泵备份)

热门文章

  1. JAVA在线考试管理系统(源代码+论文+开题报告+外文翻译+英文文献+答辩PPT)
  2. 小游戏——打鱼还是晒网
  3. 创建学生表,课程表,班级表,班级课程表
  4. Repeater控件动态变更列(Header,Item和Foot)信息
  5. 面试题整理 自问自答
  6. 验证电话号码,支持手机座机可加国家代码和区号,座机支持分机
  7. [转] 记住亦舒的话
  8. uni 登录token方法_uni-app 中保持用户登录状态
  9. 微信小程序 延时执行 设置固定时间间隔
  10. java 月份适配计算_Java8中的时间日期API这么好用,你居然还没有掌握?