1 条题解

  • 0
    @ 2026-8-31 9:04:44

    题目传送门

    题目大意

    题目不难理解,先给了你一个 nn 表示兵营的数量。
    后面又给了每个兵营里起始的工兵数量。
    以及一个兵营编号 mm 表示中立兵营的编号。
    还有三个数 p1,s1,s2p_1,s_1,s_2 分别表示天降神兵的位置,数量,第二次派兵的数量。
    让你求你手上的兵放在哪个位置可以使两个兵营中的势力差更小。

    做法

    首先,我们可以提前求一遍实力差。
    以此减小时间复杂度。
    如果是暴力的算法,每一次都要求一遍势力差,放在这一题的数据就过不了。
    所以提前求完之后,更新一下天降神兵后的势力差。
    此时,用到一个变量 kk 用于记录你手上的兵放在哪个兵营比较合适。
    这里有个坑,kk 的初始值应为 11,否则第二个点就会错。
    因为如果初始化为 00,当没有找到任何一个点的势力差小于之前统计过的势力差,就会输出 00,但很明显,此时应输出 11
    这样只要更新一遍,就可以大大减小时间复杂度。

    #include<bits/stdc++.h>
    using namespace std;
    int sum, s1, s2;
    int c[100010];
    int n, m, p1, p2, tmp;
    int main() {
    	// 优化
    	ios::sync_with_stdio(false);
    	cin.tie(0),cout.tie(0);
    	// 先照常输入
    	cin >> n;
    	for(int i=1; i<=n; i++) cin >> c[i];
    	cin >> m >> p1 >> s1 >> s2;
    	// 龙虎势力的差距
    	// 原理:当 i < m  时  sum里的就是龙势力的总势力
    	//       当 i == m 时  sum里没有改变  因为 m - i = 0
    	//       当 i > m  时  sum每一次加的都是负数 算完之后就可以求出龙虎势力差
    	for(int i=1; i<=n; i++) sum += ((m - i) * c[i]);
    	// 求出p1兵营的势力
    	sum += (m - p1) * s1;
    	// 先算势力差
    	long long cha = abs(sum + (m - 1) * s2);
    	// k表示放到哪一个兵营
    	int k = 1;
    	// 后面每一次都算一次势力差
    	for(int i=2; i<=n; i++) {
    		// 继续算势力差
    		tmp = abs(sum + ((m - i) * s2));
    		// tmp 与 cha 比较 更新最小值
    		if(tmp < cha) {
    			// 取最小值
    			cha = tmp;
    			// 调整编号
    			k = i;
    		}
    	}
    	// 输出编号
    	cout << k << '\n';
    	return 0;
    }
    

    恭喜你,这一份是不对的。
    你只要认真算后,就可以发现,要开 long long

    AC Code:

    #include<bits/stdc++.h>
    using namespace std;
    long long sum, s1, s2;
    long long c[100010];
    long long n, m, p1, p2, tmp;
    int main() {
    	// 优化
    	ios::sync_with_stdio(false);
    	cin.tie(0),cout.tie(0);
    	// 先照常输入
    	cin >> n;
    	for(int i=1; i<=n; i++) cin >> c[i];
    	cin >> m >> p1 >> s1 >> s2;
    	// 龙虎势力的差距
    	// 原理:当 i < m  时  sum里的就是龙势力的总势力
    	//       当 i == m 时  sum里没有改变  因为 m - i = 0
    	//       当 i > m  时  sum每一次加的都是负数 算完之后就可以求出龙虎势力差
    	for(int i=1; i<=n; i++) sum += ((m - i) * c[i]);
    	// 求出p1兵营的势力
    	sum += (m - p1) * s1;
    	// 先算势力差
    	long long cha = abs(sum + (m - 1) * s2);
    	// k表示放到哪一个兵营
    	int k = 1;
    	// 后面每一次都算一次势力差
    	for(int i=2; i<=n; i++) {
    		// 继续算势力差
    		tmp = abs(sum + ((m - i) * s2));
    		// tmp 与 cha 比较 更新最小值
    		if(tmp < cha) {
    			// 取最小值
    			cha = tmp;
    			// 调整编号
    			k = i;
    		}
    	}
    	// 输出编号
    	cout << k << '\n';
    	return 0;
    }
    
    • 1

    信息

    ID
    1988
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    78
    已通过
    15
    上传者