递归
NC15173 The Biggest Water Problem
简单递归,直接暴力
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
#define de(x) cout << x << " ";
#define sf(x) scanf("%d", &x);
#define Pu puts("");
#define ll long long
int n, m, ans;
int fun(int x) {
if (x / 10 == 0) {
return x;
}
int res = 0;
while (x) {
res += (x % 10);
x /= 10;
}
return fun(res);
}
int main() {
cin >> n;
cout << fun(n) << endl;
return 0;
}
NC22164 更相减损术
注意处理的时候,使用较大的值去减去较小的值
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define sf(x) scanf("%d", &x);
#define de(x) cout << x << " ";
#define Pu puts("");
const int N = 1e5 + 9, mod = 1e9 + 7;
int n, m, ans;
int fun(int x, int y) {
if (x % y == 0) {
return y;
}
int t = x - y;
if (t > y) { // 大数放前面
return fun(t, y);
} else {
return fun(y, t);
}
}
int main() {
cin >> n >> m;
cout << fun(max(n, m), min(n, m)) << endl;
return 0;
}
NC208813 求逆序数
做法一:直接暴力求解
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 2e3 + 10;
#define de(x) cout << x << " ";
#define sf(x) scanf("%d", &x);
#define Pu puts("");
#define ll long long
int n, m, ans;
int a[N];
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
sf(a[i])
}
ans = 0;
// 做法一:直接暴力求解
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
if (a[j] < a[i])
ans++;
}
}
de(ans);
return 0;
}
做法二:归并排序,在归并的过程中记录逆序对
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 2e3 + 10;
#define de(x) cout << x << " ";
#define sf(x) scanf("%d", &x);
#define Pu puts("");
#define ll long long
int n, m, ans;
int a[N], b[N];
void mesort(int l, int r) {
// de(l) de(r) de(ans) Pu;
if (l == r)
return;
int mid = l + r >> 1;
mesort(l, mid);
mesort(mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r) {
if (a[i] <= a[j])
b[++k] = a[i++];
else { // 从i-mid的数值一定都比j上的数值大
b[++k] = a[j++];
ans += mid - i + 1;
// de(l) de(r) de(mid) de(i) de(999) Pu;
}
// 会不会重复统计?
// 不会,因为归并排序我们是看左右两部分,而这两部分的长度是不断增加的
// 各个l-r区间相互独立
}
while (i <= mid)
b[++k] = a[i], i++;
while (j <= r)
b[++k] = a[j], j++;
for (int o = l, k = 0; o <= r; o++) {
a[o] = b[++k];
}
// de(l) de(r) de(ans) Pu;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
sf(a[i])
}
ans = 0;
// 做法二:归并排序,在归并的过程中记录逆序对
mesort(1, n);
de(ans);
return 0;
}
NC207028 第k小数
使用快排
#include <math.h>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 5e6 + 10;
#define de(x) cout << x << " ";
#define sf(x) scanf("%d", &x);
#define Pu puts("");
#define ll long long
int n, m, ans;
int a[N];
int k;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
int find_qsort(int l, int r) {
if (l == r)
return a[l];
int mid = a[l + r >> 1];
int i = l, j = r;
while (i <= j) {
while (a[j] > mid)
j--;
while (a[i] < mid)
i++;
if (i <= j) {
swap(a[i], a[j]);
i++;
j--;
}
}
if (k <= j)
find_qsort(l, j);
else if (k >= i)
find_qsort(i, r);
return a[k];
}
int main() {
int T;
cin >> T;
while (T--) {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
a[i] = read();
}
cout << find_qsort(1, n) << endl;
}
return 0;
}