01 乘方(pow)

无厘骗分:(60分)

#include <bits/stdc++.h>
using namespace std;

long long a, b;

int main() {
    freopen("pow.in", "r", stdin);
    freopen("pow.out", "w", stdout);
    
    cin >> a >> b;
    
    if (b == 1) {
        cout << a << endl;
    } else if (b == 2) {
        cout << a * a << endl;
    } else {
        cout << -1 << endl;
    }
    
    return 0;
}

暴力解法:使用 pow 函数 (70分)

#include<bits/stdc++.h>
using namespace std;

long long a, b, sum = 1;

int main() {
	freopen("pow.in", "r", stdin);
	freopen("pow.out", "w", stdout);
	
	cin >> a >> b;

	sum = pow(a, b);

	if (sum > 1e9) {
		cout << -1 << endl;
	} else {
		cout << sum << endl;
	}

	return 0;
}

满分正解:pow() 函数

#include<bits/stdc++.h>
using namespace std;

long long a, b;

int main() {
	freopen("pow.in", "r", stdin);
	freopen("pow.out", "w", stdout);
	
	cin >> a >> b;

	if (pow(a, b) > 1e9) {
		cout << -1 << endl;
	} else {
		cout << fixed << setprecision(0) << pow(a, b) << endl;
	}

	return 0;
}

满分正解:逐次累乘

#include<bits/stdc++.h>
using namespace std;

// 注意要用 long long 
long long a, b, sum = 1; // 全局变量只能自动置零 
bool flag = false; // 判断 结果是否溢出 
	
int main() {
	freopen("pow.in", "r", stdin);
	freopen("pow.out", "w", stdout);

	cin >> a >> b;
	
	if (a == 1) { // 当 a 为 1 时, b 是 任何数,结果都是 1 
		cout << 1 << endl;
	} else if (b > 30) { // 即使 a 最小  (a = 2),b 超过 30,结果 一定 超过 1e9 
		cout << -1 << endl;
	} else {
		for (long long i = 1; i <= b; i++) {
			sum = sum * a; // 将乘方转换为累成 
			if (sum > 1e9) { // 若溢出,则标记 
				flag = true;
				break;
			}
		}
		// 根据 flag 溢出标记 输出结果 
        if (flag) {
            cout << -1 << endl;
        } else {
            cout << sum << endl;
        }
	}

	return 0;
}

02 解密(decode)

暴力枚举:(60分)

#include <bits/stdc++.h>
using namespace std;

int k, n, e, d, p, q;
bool found;
    
int main() {
	freopen("decode.in", "r", stdin);
	freopen("decode.out", "w", stdout);
	
	cin >> k;
    
	for (int i = 1; i <= k ; i++) {
		cin >> n >> d >> e;
		found = false;
		// 根据 方程 穷举 p 和 q 
		for (p = 1; p * p <= n; p++) {
			if (n % p != 0)
				continue;
			q = n / p;
			if (e * d == (p - 1) * (q - 1) + 1) {
				cout << p << " " << q << endl;
				found = true; // 标记 已找到结果 
				break;
			}
		}
		if (!found)
			cout << "NO" << endl;
	}
	return 0;
}

暴力枚举:(60分)

#include <bits/stdc++.h>
using namespace std;

long long k, n, d, e, m; 

int main() {
    freopen("decode.in", "r", stdin);
    freopen("decode.out", "w", stdout);
    
    cin >> k;

    // p * q = n;
    // p + q = m;
    while (k--) {
        cin >> n >> d >> e;
        m = n - e * d + 2;
        bool flag = false;
        for (int i = 1; i * i <= n; i++) {
            if (n % i != 0) continue;
            if (i * (m - i) == n) {
                cout << i << " " << m - i << endl;
                flag = true;
                break;
            }
        }
        if (!flag) cout << "NO" << endl;
    }

    return 0;
}

满分正解:一元二次方程 求根公式

#include <bits/stdc++.h>
using namespace std;

int k, p, q, ans;
long long n, e, d, m, delta;

int main() {
	freopen("decode.in", "r", stdin);
	freopen("decode.out", "w", stdout);
    
	cin >> k;
    
	for (int i = 1; i <= k; i++) {
		cin >> n >> e >> d;
        
		m = n - e * d + 2; // p + q
		delta = m * m - 4 * n;
        
		if (m <= 0) {
			cout << "NO" << endl;

		} else if (delta < 0) {
			cout << "NO" << endl;

		} else {
			double pp = (m - sqrt(m * m - 4 * n) ) / 2.0;
			p = (int)pp;
			if (p - pp != 0)
				cout << "NO" << endl;
			else {
				q = m - p;
				cout << p << " " << q << endl;
			}
		}
	}
	return 0;
}

满分正解:二分查找

#include <bits/stdc++.h>
using namespace std;

long long k, n, e, d, m;
long long l, r, mid;

int main() {
	freopen("decode.in", "r", stdin);
	freopen("decode.out", "w", stdout);
	cin >> k;
	while (k--) {
		cin >> n >> e >> d;
        // p * q = n
        // p + q = m
		m = n - e * d + 2;
        
		l = 1; // 左边界
		r = m; // 右边界
        
		while (l < r) {
			mid = l + (r - l) / 2; // 中间值
			if (mid * (m - mid) >= n) // 答案在左半区
				r = mid;
			else // 答案在右半区
				l = mid + 1;
		}
        
		if (m - l >= 1 && l * (m - l) == n)
			cout << l << " " << m - l << endl;
		else
			cout << "NO" << endl;
	}

	return 0;
}

T1 小苹果(apple)

骗分方式(50分)

// 骗分方式:n < 10 和 小苞第一天就取走编号为 n 的苹果。
// 1、2、4、6、7:50 分

/*
1 : 1 2 3 4 5 6 7 8 9 10
2 : 2 3 5 6 8 9
3 : 3 5 8 9
4 : 5 8
5 : 8
*/

#include <bits/stdc++.h>
using namespace std;

long long n, cnt;

int main() {
    freopen("apple.in", "r", stdin);
    freopen("apple.out", "w", stdout);
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin.tie(0);
    
    cin >> n;
    
    if (n == 1) {
        cout << "1 1" << endl;
    } else if (n == 2) {
        cout << "2 2" << endl;
    } else if (n == 3) {
        cout << "3 3" << endl;
    } else if (n == 4) {
        cout << "3 1" << endl;
    } else if (n == 5) {
        cout << "4 4" << endl;
    } else if (n == 6) {
        cout << "4 2" << endl;
    } else if (n == 7) {
        cout << "4 1" << endl;
    } else if (n == 8) {
        cout << "5 5" << endl;
    } else if (n == 9) {
        cout << "5 3" << endl; 
    } else if (n == 10) {
        cout << "5 1" << endl;  
    } else {
        while (n > 0) {
            cnt++;
            n -= ceil(1.0 * n / 3); // 每天都拿走苹果总数的 1 / 3,注意要向上取整
        }
        
        cout << cnt << " " << 1 << endl;
    }
    return 0;
}

模拟算法1:约瑟夫环(90分)

// 暴力枚举(约瑟夫环):90 分

// 1 : 1 2 3 4 5 6 7 8
// 2 : 2 3 5 6 8
// 3 : 3 5 8
// 4 : 5 8
// 5 : 8

#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
bool arr[N];
long long n, remain, cnt, roll, ans1, ans2;
bool found = false;

int main() {
    freopen("apple.in", "r", stdin);
    freopen("apple.out", "w", stdout);

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    cin >> n;
    // for (int i = 1; i <= n; i++) {
    //     arr[i] = true;
    // }
    memset(arr, true, sizeof(arr));

    remain = n;
    while (remain > 0) {
        cnt++;
        if (arr[cnt]) {
            roll++;
            // cout << "cnt = " << cnt << ", roll = " << roll << endl;
            if (roll == 1) {
                arr[cnt] = false;
                // cout << "arr[" << cnt << "] = false" << endl;
                remain--;
            }
            if (roll == 3) roll = 0;
        }
        if (cnt == n || remain == 0) {
            cnt = 0;
            roll = 0;
            ans1++;
            // cout << "ans1 = " << ans1 << endl;
            if (!found && !arr[n]) {
                ans2 = ans1;
                found = true;
            }
        }
    }

    cout << ans1 << " " << ans2 << endl;

    return 0;
}

模拟算法2:约瑟夫环(90分)

// 暴力枚举(约瑟夫环):90 分

// 1 : 1 2 3 4 5 6 7 8
// 2 : 2 3 5 6 8
// 3 : 3 5 8
// 4 : 5 8
// 5 : 8

#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
bool arr[N];
long long n, remain, cnt, roll, ans1, ans2;
bool found = false;

int main() {
    freopen("apple.in", "r", stdin);
    freopen("apple.out", "w", stdout);

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    cin >> n;
    // for (int i = 1; i <= n; i++) {
    //     arr[i] = true;
    // }
    memset(arr, true, sizeof(arr));

    remain = n;
    while (remain > 0) {
        ans1++;
        roll = 2;
        for (int i = 1; i <= n; i++) {
            if (arr[i]) roll++;
            if (roll == 3) {
                arr[i] = false;
                remain--;
                roll = 0;
                if (i == n) ans2 = ans1;
            }
        }
    }

    cout << ans1 << " " << ans2 << endl;

    return 0;
}

满分正解(数学分析)

// 满分正解:数学分析

// 1 : 1 2 3 4 5 6 7 8
// 2 : 2 3 5 6 8
// 3 : 3 5 8
// 4 : 5 8
// 5 : 8

#include <bits/stdc++.h>
using namespace std;

long long n, remain, removeCnt, ans1, ans2;
bool found = false;

int main() {
    freopen("apple.in", "r", stdin);
    freopen("apple.out", "w", stdout);

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> n;

    remain = n;

    while (remain > 0) {
        ans1++;
        if (!found && remain % 3 == 1) {
            ans2 = ans1;
            found = true;
        } 
        removeCnt = ceil(1.0 * remain / 3);
        remain -= removeCnt;
    }

    cout << ans1 << " " << ans2 << endl;

    return 0;
}

满分正解(数学+模拟)

//满分正解:数学+模拟

#include<bits/stdc++.h>
using namespace std;

int main() {
    freopen("apple.in", "r", stdin);
    freopen("apple.out", "w", stdout);
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
	int n;
	cin >> n;
	if (n <= 3) {
		cout << n << " " << n << endl;
		return 0;
	}
    
	int day = 0, ans = 0;
	while (n > 3) {
		day++;
		if (!ans && n % 3 == 1) ans = day;
		n -= ceil(1.0 * n / 3);
		if (n <= 3) {
			day += n;
			if (!ans) ans = day;
			break;
		}
	}
	cout << day << " " << ans << endl;

	return 0;
}

满分正解:最简洁代码

#include <bits/stdc++.h>
using namespace std;

// ans1 : 所有苹果被拿走的总共天数
// ans2 : 编号为 n 的苹果被拿走的天数
long long n, ans1, ans2;

int main() {
    freopen("apple.in", "r", stdin);
    freopen("apple.out", "w", stdout);
    cin >> n;
    while (n) {
        ++ans1;
        if (!ans2 && n % 3 == 1) ans2 = ans1;
        n -= ceil(1.0 * n / 3);
    }
    cout << ans1 << " " << ans2 << endl;
    return 0;
}
#include <cstdio>

int main() {
    char k[110], c[1010], cc[1010],
        m[1010];  // k为密钥,c为密文,cc为转大写后的密文,m为明文
    scanf("%s\n%s", k, c);
    for (int i = 0, j = 0; c[i]; i++, j++)  // 遍历c, i为c的下标, j为k的下标
    {
        if (!k[j]) j = 0;                  // k到头, 从第0个又开始遍历
        if (k[j] > 'Z') k[j] = k[j] - 32;  // k转大写
        if (c[i] > 'Z')
            cc[i] = c[i] - 32;  // c转大写, 存到cc里
        else
            cc[i] = c[i];
        m[i] = (cc[i] - 'A') - (k[j] - 'A');  // 密文 - 密钥 = 明文
        if (m[i] < 0) m[i] += 26;
        if (c[i] > 'Z')
            m[i] += 'a';  // 考虑小写
        else
            m[i] += 'A';
        if (!c[i + 1])
            cc[i + 1] = 0,
                   m[i + 1] = 0;  // 给新生成的字符数组结尾加上\0, 防止乱码
    }
    printf("%s", m);
}

密码合规

#include <bits/stdc++.h>
using namespace std;
bool check(string x) {
    int a = 0, A = 0, d = 0, f = 0;
    for (int i = 0; i < x.length(); i++) {
        if (x[i] >= 'a' && x[i] <= 'z') {
            a = 1;
        } else if (x[i] >= 'A' && x[i] <= 'Z') {
            A = 1;
        } else if (x[i] >= '0' && x[i] <= '9') {
            d = 1;
        } else if (x[i] == '!' || x[i] == '@' || x[i] == '#' || x[i] == '$') {
            f = 1;
        } else {
            return false;
        }
    }
    if (f == 0)
        return false;
    if (a + A + d < 2)
        return false;
    return true;
}

int main() {
    string s;
    cin >> s;
    string t = "";
    for (int i = 0; i < s.length(); i++) {
        if (s[i] != ',') {
            t += s[i];
        } else {
            if (check(t)) {
                cout << t << endl;
            }
            t = "";
        }
    }
    if (check(t)) {
        cout << t << endl;
    }
    return 0;
}

T1 赚钱(money)

暴力穷举(30分)

// 暴力穷举:30分

#include <bits/stdc++.h>
using namespace std;

const int N = 200000 + 10;
long long arr[N];
long long n;
long long ans = -1e18;   //打擂台 极小值

int main() {


	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
	}

	for (int i = 1; i < n; i++) { // 从第 1 天遍历到第 n-1 天,最后一天不能买
		for (int j = i + 1; j <= n; j++) { // 从第 i + 1 天遍历到第 n 天
			ans = max(ans, arr[j] - arr[i]); // 求出 两两相比,差价的最大值
		}
	}

    cout << ans << endl;
    
	return 0;
}

满分正解(贪心算法)

// 满分正解:贪心算法

#include <bits/stdc++.h>
using namespace std;

const int N = 200000 + 10;
long long arr[N];
long long n, buy, sell;
long long ans = -1e18;   //打擂台 极小值

int main() {

	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
	}

	// 总体思想:低买高卖
	buy = arr[1]; // 第一天为买入
	for (int i = 2; i <= n; i++) { // 从第 2 天遍历到第 n 天
		sell = arr[i];
		ans = max(ans, sell - buy); // 打擂台,求相邻两天的最大差价
		if (buy >= sell) buy = sell; // 如果前一天比后一天的价格高,买入转移
	}

	cout << ans << endl;

	return 0;
}

选手代码

#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;

int n;
long long num[N];
long long minn = 1e18;
long long maxx = -1e18;
int main() {
	freopen("money.in", "r", stdin);
	freopen("money.out", "w", stdout);
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> num[i];
	for (int i = 1; i <= n; i++) {
		maxx = max(num[i] - minn, maxx);
		minn = min(minn, num[i]);
	}
	cout << maxx;
	return 0;
}

T2 回文字符串(palindrome)

骗分方式(10分)

// 骗分方式:10 分

#include <bits/stdc++.h>
using namespace std;

int main() {
    freopen("palindrome.in", "r", stdin);
    freopen("palindrome.out", "w", stdout);

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
       
    cout << "NO" << endl;
    
    return 0;
}

特殊性质(40分)

// 特殊性质:其中有 30% 的数据输入的字符串为回文字符串;
// 1、2、3、4:40 分

#include <bits/stdc++.h>
using namespace std;

string s, sRev;

int main() {
	freopen("palindrome.in", "r", stdin);
	freopen("palindrome.out", "w", stdout);

	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> s;

    sRev = s;
    reverse(sRev.begin(), sRev.end()); // 时间复杂度:O(n / 2)
    
    if (sRev == s) {
    	cout << "YES" << endl << s.size() << endl;
    } else {
        cout << "NO" << endl;
    }
    
	return 0;

}

满分正解(双指针算法)

// 满分正解:双指针算法
// 100 分

#include <bits/stdc++.h>
using namespace std;

string s;
long long res;

int main() {
	freopen("palindrome.in", "r", stdin);
	freopen("palindrome.out", "w", stdout);

	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> s;
    
    // 特判:如果s的长度等于1,那么只能分出S1 = s,此时n = 1,不满足n >= 2的条件
	if (s.size() == 1) { 
		cout << "NO" << endl;
		return 0;
	}
    
    // 双指针算法
	string a = "", b = "", c = ""; // a,b,c分别表示Si,Sn - i + 1,(Sn - i + 1的回文字符串)
	for (int i = 0, j = s.size() - 1; i <= j; i++, j--) { // 两个指针i,j分别从首尾开始移动
		a += s[i];
		b = s[j] + b;
		c += s[j];
		// 需要满足i != j,例如aba这种情况,最终 a = "b", b = "b", c = "b",显然不能分割成两个字串
		if (i != j && (a == b || a == c)) { 
			res += 2;
			a = "", b = "", c = "";
		}
	}
    
	// 如果分割后 a 非空,则例如 abca,最终 a = "bc",也为一个字串
	if (a != "") { 
		res++;
	}

	// 若 res 为 1,则一共只分出了 1 个字串,不满足 n >= 2
	if (res == 1) { 
		cout << "NO" << endl;
	} else {
		cout << "YES" << endl << res << endl;
	}
    
	return 0;

}

李泽轩 双指针 满分算法

#include <bits/stdc++.h>
using namespace std;

int main() {
	freopen("palindrome.in", "r", stdin);
	freopen("palindrome.out", "w", stdout);
	string s;
	cin >> s;
	int l = 0, r = s.size() - 1;
	int cnt = 0;
	while (l <= r) {
		string a, b;
		a += s[l];
		b = s[r] + b;
		l++, r--;
		while(a != b && l <= r) {
			a += s[l];
			b = s[r] + b;
			l++, r--;
		}
		if(a == b || l > r) {
			cnt += 2;
			if(a != b || l == r) {
				cnt--;
			}
		}
	}
	if(cnt <= 1) {
		cout << "NO" << endl;
	} else {
		cout << "YES" << endl;
		cout << cnt << endl;
	}
	return 0;
}

T3 克隆机(clone)

暴力枚举(60分)

// 暴力枚举:60 分

#include <bits/stdc++.h>
using namespace std;

long long k, n, seq, cnt = 1;
char arr[26 + 1] = {'0', 'A', 'B', 'C', 'D', 'E', 'F', 
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

int main() {
    freopen("clone.in", "r", stdin);
    freopen("clone.out", "w", stdout);
    cin >> k >> n;
    for (int i = 1; i <= n; i++) {
        seq++;
//        cout << "i = "<< i << ", seq = " << seq << endl;
        if (seq >= k * cnt) {
            seq = 0;
            cnt *= 2;
        }
    }
//    cout << "cnt = " << cnt << endl;
//    cout << "idx = " << (seq + cnt - 1) / cnt << endl;
    cout << arr[(seq + cnt - 1) / cnt] << endl;
    return 0;
}

满分正解(双端队列)

// 满分正解:双端队列

#include <bits/stdc++.h>
using namespace std;

deque<pair<char, long long>> dq;
pair<char, long long> now;
long long k, n;

int main() {
	freopen("clone.in", "r", stdin);
	freopen("clone.out", "w", stdout);

	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> k >> n;
    
	for (int i  = 1; i <= k; i++) {
		char ch = (char)('A' + i - 1);
		dq.push_back(make_pair(ch, 1));
	}
    
	while (!dq.empty()) {
		now = dq.front();
		dq.pop_front();
		n = n - now.second;
		// cout << now.first << " : " << now.second << endl;
		if (n <= 0) {
			cout << now.first << endl;
			return 0;
		} else {
			dq.push_back(make_pair(now.first, now.second * 2LL));
		}
	}

	return 0;
}

满分正解(数学分析)

// 满分正解:数学分析

#include <bits/stdc++.h>
using namespace std;

long long  k, n, t, sum;

int main() {
    freopen("clone.in", "r", stdin);
    freopen("clone.out", "w", stdout);
    
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> k >> n;
    
	t = log2(n / k + 1);
	sum = n - (long long)(pow(2, t) - 1) * k;
	cout << (char)('A' + ceil(sum / pow(2, t)) - 1);
    
	return 0;
}

李泽轩 考场 满分解法

#include <bits/stdc++.h>
using namespace std;

long long k, n, cnt = 1;

int main () {
	freopen("clone.in", "r", stdin);
	freopen("clone.out", "w", stdout);
	cin >> k >> n;
	while(n - k * cnt > 0) {
		n -= k * cnt;
		cnt *= 2; 
	}
	cout << char(ceil(n * 1.0 / cnt) + 64) << endl;
	return 0;
}

T4 代价(cost)

李泽轩 暴力枚举(50分)

#include <bits/stdc++.h>
using namespace std;

long long n, A, B;
long long mc = 1e18;
long long arr[100005];

int main() { 
	freopen("cost.in", "r", stdin);
	freopen("cost.out", "w", stdout);
	cin >> n >> A >> B;
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
	}
	sort(arr + 1, arr + n + 1);
	for(int i = 1; i <= n; i++) {
		long long cnt = 0;
		for(int j = 1; j < i; j++) {
			cnt += (arr[i] - arr[j]) * A;
		}
		for(int j = i + 1; j <= n; j++) {
			cnt += (arr[j] - arr[i]) * B;
		}
		if(mc > cnt) {
			mc = cnt;
		}
	}
	cout << mc << endl;
	return 0;
}

满分正解(暴力枚举)

// 满分正解:暴力枚举

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
long long arr[N];
long long n, costA, costB;
long long cntFront, cntBack, res = 1e18;   // 最初状态,结果

int main () {
	freopen("cost.in", "r", stdin);
	freopen("cost.out", "w", stdout);

	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> costA >> costB;
	for (int i = 1; i <= n; i++) cin >> arr[i];

	sort(arr + 1, arr + 1 + n);

	for (int i = 2; i <= n; i++) {
		cntBack = cntBack + (arr[i] - arr[1]);
	}
	// cout << "cntBack = " << cntBack << endl;

	for (int i = 2; i <= n; i++) { // 枚举,动态维护 cntFront 和 cntBack
		cntFront = cntFront + (long long)(arr[i] - arr[i - 1]) * (i - 1);
		cntBack = cntBack - (long long)(arr[i] - arr[i - 1]) * (n - i + 1);
		// cout << cntFront << ", " << cntBack << endl;
		res = min(res, cntFront * costA + cntBack * costB);
	}

	cout << res << endl;

	return 0;
}

满分正解(前缀和)

// 满分正解:前缀和

#include<bits/stdc++.h>
using namespace std;

const int N = 100000 + 10;
long long arr[N], sum[N];
long long n, costA, costB;
long long frontSum, backSum, curCost, ans = 1e18;

int main () {
    freopen("cost.in", "r", stdin);
    freopen("cost.out", "w", stdout);
    
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> costA >> costB;
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
	}

	sort(arr + 1, arr + 1 + n); // 排序

	for (int i = 1; i <= n; i++) {
		sum[i] = sum[i - 1] + arr[i]; // 预处理 前缀和
	}

	for (int i = 1; i <= n; i++) {
		frontSum = sum[i - 1];     // 当前位置 之前 所有产品规格之和
		backSum = sum[n] - sum[i]; // 当前位置 之后 所有产品规格之和
		// 所有产品 改为 当前位置的 代价
		curCost = ((long long)(i - 1) * arr[i] - frontSum) * costA 
		+ (backSum - (long long)(n - i) * arr[i]) * costB; 
		// 打擂台 求 所有位置 的 代价 的 最小值
		ans = min(ans, curCost);
	}

	cout << ans << endl;

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

struct person {
    int id;
    string name;
    string work_id;
    string dept_id;
};

const int N = 1e6;
person arr[N + 1];

int main() {
    int n, id, type;
    cin >> n;
    
    for (int i = 1; i <= 3 * n; i++) {
        cin >> id >> type;
        if (type == 2) {
            cin >> arr[id].name;
        } else if (type == 3) {
            cin >> arr[id].work_id;
        } else {
            cin >> arr[id].dept_id; 
        }
    }
    
    for (int i = 1; i <= 3; i++) {
        cout << i << " " << arr[i].name << " "
        << arr[i].work_id << " " << arr[i].dept_id << endl;
    }
    
    return 0;
}

CSP-X 2022 小学组 比赛试题 解析


01 疯狂的数列(crazy)

暴力解法

#include <bits/stdc++.h>
using namespace std;

int main() {
    freopen("crazy.in", "r", stdin);
    freopen("crazy.out", "w", stdout);
    
    int n;
    unsigned long long num = 0;
    int cnt = 0;
    cin >> n; 
    for (int i = 1; i <= n; i++) {
        num = num * 10 + i;
        if (num % 3 == 0) {
            cnt++;
        }
    } 
    cout << cnt << endl;
     
    return 0;
}

部分测试点:所有数位之和被3整除

#include <bits/stdc++.h>
using namespace std;

int main() {
    freopen("crazy.in", "r", stdin);
    freopen("crazy.out", "w", stdout);
    
    long long n, ii, num, sum = 0, cnt = 0;
    cin >> n; 
    
    for (int i = 1; i <= n; i++) {
        ii = i;
        while (ii > 0) {
            num = ii % 10;
            sum += num;
            ii /= 10;
        }
        if (sum % 3 == 0) {
            cnt++;
        }
    } 
    cout << cnt << endl;
     
    return 0;
}

满分正解

#include <bits/stdc++.h>
using namespace std;

int main() {
    freopen("crazy.in", "r", stdin);
    freopen("crazy.out", "w", stdout);
    
    long long n, sum = 0, cnt = 0;
    cin >> n;
    
    for(int i = 1; i <= n; i++) {
    	sum += i;
    	if(sum % 3 == 0){
    		cnt++;
		}
    }

    sum = (1 + n) * n / 2;

    sum % 3 == 0

    cout << cnt << endl;
     
    return 0;
}

02发送快递(express)

部分测试点:无分组

#include <bits/stdc++.h>
using namespace std;

int arr[100000 + 1];    // 全局变量数组,无需 memset 置零

int main() {
    freopen("express.in", "r", stdin);
    freopen("express.out", "w", stdout);
    
    // 本算法仅处理 无分组 (s=0) 的情况 
    int n, m, cnt = 0, sum;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
    } 
    sort(arr + 1, arr + 1 + n); // 升序排序 
    
    // 设计首尾游标 (各自向中间靠近) 
    int flagHead = 1, flagTail = n; 
    while (flagHead <= flagTail) { // 循环条件为首尾游标不相遇 
        // 先考虑 队尾部分 充分打包 
        sum = arr[flagTail];        
        while (sum <= m) {
            flagTail--;
            sum += arr[flagTail];
        }
        sum -= arr[flagTail]; // 将最后一次不符条件的重量去除 
        //  再考虑 队首部分 充分打包 
        sum +=  arr[flagHead];
        while (sum <= m) {
            flagHead++;
            sum += arr[flagHead];
        }
        sum -= arr[flagHead]; // 将最后一次不符条件的重量去除 
        // 重新归零,进行下一次打包 
        if (sum > 0) {
            cnt++;
            sum = 0;
        }
    }
    cout << cnt << endl;
    return 0;
}

满分正解

无

03 成绩排名(sort)

满分正解:sort函数

#include <bits/stdc++.h>
using namespace std;

    int n, m, cnt = 0;
    int arr[10000 + 1];
    
int main() {
    freopen("sort.in", "r", stdin);
    freopen("sort.out", "w", stdout);
    memset(arr, 0, sizeof(arr));
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
    } 
    cin >> m;
    sort(arr + 1, arr + 1 + n, greater<int>());
    for (int i = 1; i <= n; i++) {
        if (arr[i] > m) {
            cnt++;
        }
    }
    cout << cnt + 1 << endl;
    return 0;
}

满分正解:桶排序

#include <bits/stdc++.h>
using namespace std;

int main() {
    freopen("sort.in", "r", stdin);
    freopen("sort.out", "w", stdout);
    int n, m, num, cnt = 0;
    int arr[100 + 1];
    memset(arr, 0, sizeof(arr));
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> num;
        arr[num]++;
    } 
    cin >> m;
    for (int i = 100; i >= 0; i--) {
        if (i > m && arr[i] > 0) {
            cnt += arr[i];
        }
    }
    cout << cnt + 1 << endl;
    return 0;
}

04 口袋(pocket)

满分正解

#include <bits/stdc++.h>
using namespace std;

char x[100005], s[200005];  // 喜欢数字 和 给定数字 
int sumx[10], sums[10];     // 喜欢数字 和 给定数字 的 每种数字 的 个数 

int main() {
    
    freopen("pocket.in", "r", stdin);
    freopen("pocket.out", "w", stdout); 
    
	cin >> x >> s;         // 读入数字字符串 
	int lx = strlen(x), ls = strlen(s);    // 计算数字字符串长度
    
    // 将 喜欢数字 进行一致性处理:数字中 5 替换成 2,9 替换成 6 
	for (int i = 0; i != lx; i++) {
		int c = x[i] - '0';
		if (c == 5)
			c = 2;
		if (c == 9)
			c = 6;
		sumx[c]++;    // 累加每位数字的个数 
	}
	// 将 给定数字 进行一致性处理:数字中 5 替换成 2,9 替换成 6 
	for (int i = 0; i != ls; i++) {
		int c = s[i] - '0';
		if (c == 5)
			c = 2;
		if (c == 9)
			c = 6;
		sums[c]++;    // 累加每位数字的个数 
	}
	
	int ans = 0x7FFFFFFF; // 打擂台,设置极大值
     
	for (int i = 0; i <= 9; i++) {  // 遍历 10 中数字 
		if (sumx[i]) {
		    // 比较 喜欢数字 和 给定数字 的 每一位数字 的 倍数关系 
			ans = min(ans, sums[i] / sumx[i]);
        }
    }
    
    // 输出最小的倍数关系 
	cout << ans << endl;
	
    return 0;
}