本题较为基础,套用快排模板,利用指针的移动交换完成排序
代码如下:
#include2,P1177 【模板】快速排序using namespace std; const int N = 1e6 + 10; int a[N]; int n; long long m; void quick(int a[], int l, int r) { if (l >= r) return; int x = a[(l + r) / 2], i = l - 1, j = r + 1; while (i < j) { do i++; while (a[i] < x); do j--; while (a[j] > x); if (i < j) swap(a[i], a[j]); } quick(a, l, j); quick(a, j + 1, r); } int main() { scanf("%d%lld", &n,&m); for (int i = 0; i < m; i++) scanf("%d", &a[i]); quick(a, 0, m - 1); for (int i = 0; i < m; i++) printf("%d ", a[i]); return 0; }
存存模板代码:
#include3,P1923 【深基9.例4】求第 k 小的数using namespace std; const int N =1e6+10; int a[N]; int n; void quick(int a[], int l, int r) { if (l >= r) return; int x = a[(l+r)/2], i = l - 1, j = r + 1; while (i < j) { do i++; while (a[i] < x); do j--; while (a[j] > x); if (i < j) swap(a[i], a[j]); } quick(a, l, j); quick(a, j + 1, r); } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); quick(a, 0, n - 1); for (int i = 0; i < n; i++) printf("%d ", a[i]); return 0; }
本体思路为利用排序并输出目标,在于优化排序的时间复杂度
代码如下
#includeint a[10000000]; int quick_sort(int *a,int low,int high) { int i=low,j=high; int mid=(i+j)/2; int temp1; if(a[j]a[i]) { temp1=a[i]; a[i]=a[mid]; a[mid]=temp1; } int temp=a[i]; while(i =temp) { j--; } a[i]=a[j]; while(i low) quick_sort(a,low,i-1); if(i+1 4,P1059 [NOIP2006 普及组] 明明的随机数 本题的思路是遍历数组找寻重复的数组元素,并将其重新赋值为-1,最终根据-1的个数判断重复的次数,并从第-1之后开始输出数组达成目标
代码如下
#include5,P1093 [NOIP2007 普及组] 奖学金using namespace std; const int N = 1e6 + 10; int a[N]; int n; void quick(int a[], int l, int r) { if (l >= r) return; int x = a[(l + r) / 2], i = l - 1, j = r + 1; while (i < j) { do i++; while (a[i] < x); do j--; while (a[j] > x); if (i < j) swap(a[i], a[j]); } quick(a, l, j); quick(a, j + 1, r); } int main() { int t = 0; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); quick(a, 0, n - 1); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (a[i] == a[j]) { a[j] = -1; } } if (a[i] == -1) t++; } quick(a, 0, n - 1); printf("%dn", n - t); for (int i = t; i < n; i++) printf("%d ", a[i]); return 0; } 本题思路较为明显,主要为不遗落排序的条件,仔细阅读题干
代码如下
#include6,P1781 宇宙总统using namespace std; struct person { int n;//number int c;//chinese int m;//math int e;//english int sum; }; int main() { int n1; scanf("%d", &n1); struct person s[n1], temp; for (int i = 0; i < n1; i++) { scanf("%d%d%d", &s[i].c, &s[i].m, &s[i].e); s[i].sum = s[i].c + s[i].m + s[i].e; s[i].n = i + 1; } for (int i = 0; i < n1 - 1; i++) { for (int j = 0; j < n1 - 1 - i; j++) { if (s[j].sum < s[j + 1].sum) { temp = s[j]; s[j] = s[j + 1]; s[j + 1] = temp; } } } for (int i = 0; i < n1 - 1; i++) { for (int j = 0; j < n1 - 1 - i; j++) { if (s[j].sum == s[j + 1].sum) { if (s[j].c < s[j + 1].c) { temp = s[j]; s[j] = s[j + 1]; s[j + 1] = temp; } } } } for (int i = 0; i < n1 - 1; i++) { for (int j = 0; j < n1 - 1 - i; j++) { if ((s[j].sum == s[j + 1].sum) && (s[j].c == s[j + 1].c)) { if (s[j].n > s[j + 1].n) { temp = s[j]; s[j] = s[j + 1]; s[j + 1] = temp; } } } } for (int i = 0; i < 5; i++) printf("%d %dn", s[i].n, s[i].sum); return 0; } 本题主要为结构体的成员进行遍历,之后进行字符串的比较函数strcmp找出最大成员票数的下标值
最终输出该人的顺序和最大票数
代码如下
#include7,P2676 [USACO07DEC]Bookshelf B#include using namespace std; struct person { int n;//number char a[110];//ticket int t;//length }; char ma[110] = ""; int main() { int n1, max1 = 0, k; scanf("%d", &n1); struct person s[n1]; for (int i = 0; i < n1; i++) { scanf("%s", s[i].a); s[i].n = i + 1; s[i].t = strlen(s[i].a); } for (int i = 0; i < n1; i++) { if (strlen(ma) < s[i].t || strlen(ma) == s[i].t && strcmp(ma, s[i].a ) < 0) { strcpy(ma, s[i].a); k = i; } } printf("%dn%sn", k + 1, ma); } 该题思路主要为从大到小排序,之后累加判断是否超出条件找到临界值输出,不过在排序的优化上花费许多时间,最终在观看题解的帮助下利用冒泡排序完成
代码如下
#include8,P1116 车厢重组using namespace std; const int N = 1e6 + 10; int a[N]; int n, m; int main() { int sum = 0, t = 0; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (a[j] < a[j + 1]) { int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } // for (int i = 0; i < n; i++) // printf("%d ", a[i]); // printf("nn"); for (int i = 0; i < n; i++) { sum += a[i]; t += 1; if (sum >= m) { printf("%d", t); return 0; } } } 本题即为计算排序的次数输出即可
代码如下
#include9,P1152 欢乐的跳using namespace std; int a[100000]; int n; int main() { int k = 0; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { if (a[i] > a[j]) { k++; } } } printf("%d", k); return 0; } 本题首先利用原来的数组元素进行相减。在取绝对值保存至新的数组中,在进行排序,最后判断新数组中元素是否一一对应1——n-1的元素
代码如下
#include10,P1068 [NOIP2009 普及组] 分数线划定#include using namespace std; int main() { int n, i, j = 0, t = 0, temp; scanf("%d", &n); int a[n], b[n]; for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < n; i++) { temp = a[i] - a[i + 1]; b[j] = fabs(temp); j++; } for (int i = 0; i < j - 2; i++) { for (int k = i + 1; k < j - 1; k++) { if (b[i] > b[k]) { int temp1 = b[i]; b[i] = b[k]; b[k] = temp1; } } } //for (int i = 0; i < j - 1; i++) // printf("%d", b[i]); for (int i = 1; i <= n - 1; i++) { for (int k = 0; k < j - 1; k++) { if (b[k] == i) t++; } } if (t == n - 1) printf("Jolly"); else printf("Not jolly"); return 0; } 该题在于利用给出的条件判断界定线,并在按照要求排序后输出满足条件的人数
代码如下
#include#include using namespace std; struct person { int n;//number int g;//score }; int main() { int n1, m, k, t1, k1; float t; scanf("%d%d", &n1, &m); struct person s[n1], temp; for (int i = 0; i < n1; i++) scanf("%d %d", &s[i].n, &s[i].g); for (int i = 0; i < n1 - 1; i++) for (int j = i + 1; j < n1; j++) { if (s[i].g < s[j].g) { temp = s[i]; s[i] = s[j]; s[j] = temp; } } t = m * 1.5; t1 = floor(t) - 1; k = s[t1].g; printf("%d", k); for (int i = 0; i < n1; i++) { if (s[i].g < k) { k1 = i; printf(" %dn", k1); break; } } for (int i = 0; i < n1 - 1; i++) { for (int j = i + 1; j < n1; j++) { if (s[i].g == s[j].g) { if (s[i].n > s[j].n) { temp = s[i]; s[i] = s[j]; s[j] = temp; } } } } for (int i = 0; i 11,P5143 攀爬者 该题在于用结构体保存x,y,z三个坐标数据,并以z的大小作为判断条件从小到大排序,最后按照题中所给条件输出结果,不过该题我的代码仍存在一些问题
代码如下
#include12,P1104 生日#include #include using namespace std; struct high { int x; int y; int z; }; int main() { long long n; scanf("%lld", &n); double sum = 0, sum1; struct high s[n], temp; for (int i = 0; i < n; i++) scanf("%d%d%d", &s[i].x, &s[i].y, &s[i].z); for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) { if (s[j].z > s[j + 1].z) { temp = s[j]; s[j] = s[j + 1]; s[j + 1] = temp; } } } //printf("%d %d %dn", s[i].x, s[i].y, s[i].z); for (int i = 0; i < n - 1; i++) { sum1 = (s[i].x - s[i + 1].x) * (s[i].x - s[i + 1].x) + (s[i].y - s[i + 1].y) * (s[i].y - s[i + 1].y) + (s[i].z - s[i + 1].z) * (s[i].z - s[i + 1].z); sum1 = fabs(sum1); sum1 = sqrt(sum1); sum += sum1; } printf("%.3lf", sum); return 0; } 本题为简单的结构体多次排序,年月相同情况再次进行排序即可
代码如下
#include13,P1012 [NOIP1998 提高组] 拼数using namespace std; struct person { int n;//number char name[10]; int y;//year int m;//month int d;//date }; int main() { int n1; scanf("%d", &n1); struct person s[n1], temp; for (int i = 0; i < n1; i++) { scanf("%s %d %d %d", s[i].name, &s[i].y, &s[i].m, &s[i].d); s[i].n = i + 1; } for (int i = 0; i < n1 - 1; i++) { for (int j = i + 1; j < n1; j++) { if (s[i].y > s[j].y) { temp = s[i]; s[i] = s[j]; s[j] = temp; } } } for (int i = 0; i < n1 - 1; i++) { for (int j = i + 1; j < n1; j++) { if (s[i].y == s[j].y) { if (s[i].m > s[j].m) { temp = s[i]; s[i] = s[j]; s[j] = temp; } } } } for (int i = 0; i < n1 - 1; i++) { for (int j = i + 1; j < n1; j++) { if (s[i].y == s[j].y && s[i].m == s[j].m) { if (s[i].d > s[j].d) { temp = s[i]; s[i] = s[j]; s[j] = temp; } } } } for (int i = 0; i < n1; i++) printf("%sn",s[i].name); } 本题对于现在的我仍是一道难题,在借助题解大佬的帮助下使用c++中的string的变量进行直接比较完成此题
代码如下
#include二,本周总结using namespace std; string a[30]; int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) cin >> a[i]; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (a[j] + a[i] > a[i] + a[j]) swap(a[j], a[i]); } } for (int i = 0; i < n; i++) cout << a[i]; return 0; } 1,本周投入时间较少,由于一些额外不得以避免的事情所耽误,所以写的比较匆忙,不过会在之后慢慢补上。
2,其次,本周的题型也是围绕快速排序、选择排序、冒泡排序进行解题,其中在在快速排序初步了解下也是学习甚多,也拓宽了更多的知识储备。



