acwing刷题(一)

7 篇文章 1 订阅
4 篇文章 0 订阅

1.第K个数

 思路:

代码:
 

#include<iostream>
using namespace std;
const int N = 10010;
int n, k;
int q[N];

int quick_sort(int l, int r, int k) {
	if (l >= r) {
		return q[l];
	}
	int i = l - 1, j = r + 1,x=q[l+r>>1];
	while (i < j) {
		do {
			i++;
		} while (q[i] < x);
		do{
			j--;
		}while (q[j] > x);
		if (i < j) {
			swap(q[i], q[j]);
		}
	}
	int sl = j - l + 1;
	if (k<=sl) {
		//递归左区间
		return quick_sort(l, j, k);
	}
	return quick_sort(j + 1, r, k-sl);
}

int main(void) {
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		cin >> q[i];
	}
	cout << quick_sort(0, n - 1, k) << endl;
	return 0;
}

 2.逆序对个数

思路:

 

mid就是分界点

代码:

#include<iostream>
using namespace std;
const int N = 100010;
int q[N], tmp[N];
int n;

long long merge_sort(int l, int r) {
	if (l >= r) {
		return 0;
	}
	int mid = l + r >> 1;
	long long res = merge_sort(l, mid) + merge_sort(mid + 1, r);

	int k = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r) {
		if (q[i] <= q[j]) {
			tmp[k++] = q[i++];
		}
		else {
			tmp[k++] = q[j++];
			res += mid - i + 1;
		}
	}
	while (i <= mid) {
		tmp[k++] = q[i++];
	}
	while (j <= r) {
		tmp[k++] = q[j++];
	}
	for (int i = l, j = 0; i <= r; i++, j++) {
		q[i] = tmp[j];
	}
	return res;
}
//6
//2 3 4 5 6 1
int main(void) {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> q[i];
	}
	cout << merge_sort(0, n - 1) << endl;
	return 0;
}

3.数的三次方根

很普通的一道二分查找,直接贴代码:

#include<iostream>
using namespace std;
#define eps 1e-8
int main(void) {
	double x;
	cin >> x;
	double l = -10000, r = 100000;
	while (r - l > eps) {
		double mid = (l + r) / 2;
		if (mid * mid * mid >= x) {
			r = mid;
		}
		else {
			l = mid;
		}
	}
	printf("%lf", l);
	return 0;
}

 4.前缀和

 

代码:

#include<iostream>
using namespace std;

const int N = 100010;
int n,m;
int a[N], s[N];

int main(void) {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	//求前缀和
	for (int i = 1; i <= n; i++) {
		s[i] = s[i - 1] + a[i];
	}
	while (m--) {
		int l, r;
		cin >> l >> r;
		cout << s[r] - s[l - 1] << endl; 
	}
	return 0;
}

 5.子矩阵之和(二维前缀和)

 直接套公式,代码:

#include<iostream>
using namespace std;
const int N = 1010;
int a[N][N], s[N][N];
int n, m, q;

int main(void) {
	scanf("%d %d %d", &n, &m, &q);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			scanf("%d", &a[i][j]);
		}
	}
	//初始化前缀和
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
		}
	}
	while (q--) {
		int x1, y1, x2, y2;
		scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
		printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);
	}
	return 0;
}

6.差分

 差分就是前缀和的逆运算

代码:

#include<iostream>
using namespace std;
const int N = 10010;
int n, m;
int a[N], b[N];

void insert(int l, int r, int c) {
	b[l] += c;
	b[r + 1] -= c;
}

int main(void) {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
	}
	//构造差分数组
	for (int i = 1; i <= n; i++) {
		insert(i, i, a[i]);
	}
	while (m--) {
		int l, r, c;
		scanf("%d %d %d", &l, &r, &c);
		insert(l, r, c);
	}
	//求出对区间操作之后的前缀和
	for (int i = 1; i <= n; i++) {
		a[i] = a[i - 1] + b[i];
	}
	for (int i = 1; i <= n; i++) {
		printf("%d ", a[i]);
	}
	return 0;
}

 7.差分矩阵

 

#include<iostream>
using namespace std;
const int N = 1010;
int a[N][N], b[N][N];
int n, m, q;

void insert(int x1, int y1, int x2, int y2, int c) {
	b[x1][y1] += c;
	b[x1][y2+1] -= c;
	b[x2+1][y1] -= c;
	b[x2 + 1][y2 + 1] += c;
}

int main(void) {
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			scanf("%d", &a[i][j]);
		}
	}
	//构造差分数组
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			insert(i, j, i, j, a[i][j]);
		}
	}
	while (q--) {
		int x1, x2, y1, y2,c;
		scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &c);
		insert(x1, y1, x2, y2, c);
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + b[i][j];
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值