A

#include <cstdio>
#include <algorithm>
using namespace std;
int t, n, k, num, ans;
int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d%d", &n, &k, &ans);
		for (int i = 2; i <= n; i++) {
			scanf("%d", &num);
			if (k / (i - 1) <= 0) continue;//不够移动了 
			int c = min(k / (i - 1), num); //能移动多少到第一个 
			ans += c; k -= c * (i - 1); 
		}
		printf("%d\n", ans);
	}
	return 0;
} 

B

  • 输出1的可能是能一次直接跳到终点。特判下即可。
  • 其他情况至少需要2步。 找出最大值mx 如果距离 <= 2 * mx 那么只需要2步, 如果大于的话,那么多余的部分就利用横移一次mx弥补。
#include <cstdio>
#include <algorithm>
using namespace std;
int t, n, e, num;
int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &e);
		int mx = 0, st = -1;
		for (int i = 1; i <= n; i++) {
			scanf("%d", &num); mx = max(mx, num);
			if (e == num) st = 1; //找到最大的能整除的 
		}
		if (st != -1) printf("1\n"); //代表集合中有数能一次就弄完 
		else {
			int t = 0;
			printf("%d\n", max(2, (e + mx - 1) / mx)); //如果e <= 2 * mx 那么只需要2次 否则多余的部分就用一次mx横移弥补 
		}
	}
	return 0;
}