8.约瑟夫问题的实现
分析
- 创建一个队列和一个计数器,计数器初值为0,
- 判断队列成员数是否为1,如果不是转3,是转6
- 计数器每次+1并且对k取余,然后将队首出队
- 如果计数器值为0,那么回到2继续执行,如果不是0,转到5
- 将出队的元素再次入队,然后转2继续执行
- 输出这个仅剩队列成员的编号,即为结果
代码
#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;int man[100000];int main() {int n, k;scanf("%d %d", &n, &k);queue<int> order;for (int i = 1; i <= n; i++) {man[i] = i;order.push(man[i]);}int i = 0;while (order.size() != 1) {int temp = order.front();order.pop();i++;i %= k;if (i != 0) {order.push(temp);}}printf("%d", order.front());order.pop();return 0;
}
9.上升序列
分析
- 将输入的数字序列存放在数组a中,同时也创建一个数组a的副本——数组b
- 对数组b进行排序
- 比较数组a和数组b元素开始出现不同的序号x和最后一次出现不同的序号y
- y-x+1即为结果值,注意,可以设置初始x=0,y=-1
代码
#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;int a[100000];
int b[100000];int main() {int n;while (scanf("%d", &n) != EOF) {for (int i = 0; i < n; i++) {scanf("%d", &a[i]);b[i] = a[i];}sort(b, b + n);int p[2] = {0, -1}, k = 0;for (int i = 0; i < n; i++) {if (a[i] != b[i]) {if (k == 0) {p[k++] = i;} else {p[k] = i;}}}printf("%d\n", p[1] - p[0] + 1);}return 0;
}
10.车厢的重组
分析——冒泡排序
分析题目特性可以知道,必须是相邻的元素才能够交换,那么显然就是冒泡排序求交换的次数
代码
#include <cstdio>
#include <queue>
#include <cmath>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;int a[100000];int main() {int n;while (scanf("%d", &n) != EOF) {for (int i = 0; i < n; i++) {scanf("%d", &a[i]);}int counts = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < n - 1 - i; j++) {if (a[j] <= a[j + 1]) {continue;}swap(a[j], a[j + 1]);counts++;}}printf("%d\n", counts);}return 0;
}