标签:int sum1 --- ++ 出错 include 模拟
Point
1.模拟题及类似题减少出错方法:简化逻辑,优化数据结构,比如这道题将数组前缀和化就思路比较简单
2.这个模拟过程易出错原因有两点:1,变量到底能不能变,若不能变,加个const!2.分情况要分类好,没分类好的话,模拟很易错,会考虑不全面。分类好的话,思维教清楚,还是可以用的。
3.最好的模拟是思维简单化
题
二分模拟
https://codeforces.com/contest/1530/problem/C
题意:a从k场比赛中选分数最高的k-k/4场比赛得分和作为总得分,b也是。之后加赛n场,这n场中a每场得100分,b得0分,问n最小为几时使得a总分>=b总分。
传统模拟思维,一场场比赛加,看需加几场。代码如下:
//用自己写的快排超时了,虽然只有10万的数据,但是当输入的数据有序的时候,复杂度为O(n*n),超时,保证不超时需考虑算法最坏情况。
//避免方法:直接用stl的sort好多了
//模拟题及类似题减少出错方法:简化逻辑,优化数据结构,比如这道题将数组前缀和化就思路比较简单
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int a[111111];
int b[111111];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
const int n2=n;
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++) scanf("%d",&b[i]);
sort(a,a+n,greater<>());
sort(b,b+n,greater<>());
int k=n-n/4;
int k1=k,k2=k;
int sum1=0,sum2=0;
for(int i=0;i<k;i++) sum1+=a[i];
for(int i=0;i<k;i++) sum2+=b[i];
int ans=0;
if(sum1>=sum2) printf("0\n");
else{
while(sum1<sum2){//这个模拟过程易出错原因有两点:1,变量到底能不能变,若不能变,加个const!2.分情况要分类好,没分类好的话,模拟很易错,会考虑不全面。分类好的话,思维教清楚,还是可以用的。
sum1+=100;
if((n+1)/4-n/4){
if(k1){
sum1-=a[k1-1];
k1--;
}
else{
sum1-=100;//可以不要,因为不会出现这种情况
}
}
else{
if(k2<n2){
sum2+=b[k2];
k2++;
}
}
n++;
ans++;
}
printf("%d\n",ans);
}
}
return 0;
}
//打破传统模拟思维,即一场场比赛加,而采用这道题最简单的思维,
//即在s的范围(0,n)中找到一个最小额外场数s,使得n+s场恰好满足题意,采用二分查找,复杂度log2n,很快!
//核心函数chk也是直接依照题意计算,几乎不可能出错,虽然这个计算重复了,
//但是因为二分查找很快,所以这个函数调用次数少,不会超时!
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 200005;
int a[maxn], b[maxn];
int n;
bool chk(int s) {
vi u(n + s), v(n + s);
for (int i = 0; i < n; i++)
u[i] = a[i + 1], v[i] = b[i + 1];
for (int i = n; i < n + s; i++)
u[i] = 100, v[i] = 0;
sort(u.begin(), u.end());
sort(v.begin(), v.end());
reverse(u.begin(), u.end());
reverse(v.begin(), v.end());
int res = (n + s) - (n + s) / 4;
ll sum = 0;
for (int i = 0; i < res; i++)
sum += u[i] - v[i];
if (sum >= 0) return 1;
return 0;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
scanf("%d", &b[i]);
int l = 0, r = n;
while (l < r) {
int mid = (l + r) / 2;
if (chk(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", l);
}
return 0;
}
标签:int,sum1,---,++,出错,include,模拟 来源: https://blog.csdn.net/weixin_45727188/article/details/118876730
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。