
1. 数学老师的第一课【算法赛】
签到题:数几个字
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
cout<<20;
return 0;
}
2. 课本分配【算法赛】
思路 : 限制越大 给 越大的值 保证每个人拿到不超限制的最大
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int n,m;
cin>>n>>m;
vector<int> v(n),s(m);
for(int i=0;i<n;i++){
cin>>v[i];
}
for(int j=0;j<m;j++){
cin>>s[j];
}
int ans = 0;
sort(v.rbegin(),v.rend());
sort(s.rbegin(),s.rend());
int idx = 0;
for(int i=0;i<m;i++){
for(;idx<n;idx++){
if(v[idx] <= s[i]){
ans += v[idx];
idx++;
break;
}
}
}
cout<<ans;
return 0;
}
3. 开学考核【算法赛】
思路 : 最大值最小化 : 二分最大值是否可以在k次达到 , 注意l,r取值
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int n,k,x;
cin>>n>>k>>x;
vector<int> a(n);
int mx = 0;
for(int i=0;i<n;i++){
cin>>a[i];
if(a[i] > mx){
mx = a[i];
}
}
int l = mx - k * x; //最差情况 : 最大值一直减
int r = mx; // 最好情况 : 最大值不变
int ans = mx;
while(l <= r){
int mid = (l + r) / 2;
int num = 0;
for (auto i:a){
if (i > mid){
num += (i - mid + x - 1) / x;
if(num > k) break;
}
}
if(num <= k){
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
cout<<ans;
return 0;
}
4. 新学期征程【算法赛】
思路:奇偶 分为四类, 组合数
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
// 快速幂
int p(int a,int b){
int res=1;
while(b){
if(b&1) res = (res * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return res;
}
signed main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
// 4种点数量 : 奇偶相同是ok
int c0 = ((n+1)/2) * ((n+1)/2); // 奇 奇
int c1 = ((n+1)/2) * (n/2); // 奇 偶
int c2 = (n/2) * ((n+1)/2); // 偶 奇
int c3 = (n/2) * (n/2); // 偶 偶
int c[4] = {c0, c1, c2, c3};
int ans=0;
for (int i=0;i<4;i++) { //枚举找中点是格点的点
if (c[i] < 2) continue; //不够两个
int p1 = c[i] * (c[i]-1) % mod * p(2, mod-2) % mod; // 组合数 c[i]里选2个
int p2=1;
for (int j=0;j<4;j++) { //其他类型的不满足条件的
if (j == i) continue;
p2 = p2 * c[j] % mod;
}
ans = (ans + p1 * p2) % mod;
}
cout<<ans<<endl;
}
return 0;
}
5. 开学采购【算法赛】
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
int n;
cin>>n;
vector<int> a(n), b(n);
int suma=0,sumb=0;
for(int i=0;i<n;i++){
cin>>a[i];
suma+=a[i];
}
for(int i=0;i<n;i++){
cin>>b[i];
sumb+=b[i];
}
int m = (n + 1) / 2;
// 桥
vector<int> d(n); // B -> A
for (int i=0;i<n;i++) {
d[i] = a[i]-b[i];
}
sort(d.begin(), d.end());
//统计变便宜的
int fu=0;
while (fu < n && d[fu] < 0) fu++;
int w1=0;
for (int i = 0; i < fu; i++) {
w1 += d[i];
}
// 负的不够m个
if (fu < m) {
for (int i = fu; i < m; i++) {
w1 += d[i];
}
}
// 蓝
vector<int> c; //A -> B
for (int i=0;i<n;i++) {
int z = b[i] - a[i];
if (z > 0) { // 只要正
c.push_back(z);
}
}
sort(c.rbegin(),c.rend());
int w2=0;
int len=c.size();
// 最多选择n-m个商品从A店改到B店
for (int i=0;i<min(len, n - m);i++) {
w2 += c[i];
}
// 小蓝的最大花费 = 全在A店购买的总价 + 从A改到B增加的花费
// 小桥的最小花费 = 全在B店购买的总价 + 从B改到A减少的花费
cout<<suma + w2<<" "<<sumb + w1;
return 0;
}
1171

被折叠的 条评论
为什么被折叠?



