2022.3.7
作者:互联网
蓝书
AcWing 100. IncDec序列
思路:一开始想的是每个数都减去一个数,以为是平均值,后面想到差分就让每个数减去它前面一个构造了差分数组,因为我们最终是要让序列的每一个数都一样,所以我们让b[1]=a[1],让b[2-n]变成0,预处理出2-n的正数和z和负数和f,一部分的操作次数就是现在z和f消去一部分即min(z,f),剩下一部分我们考虑与a[1]相消去,于是答案为min(z,f)+abs(z-f),这里有abs(z-f)+1种排列方式,+1是因为z和f可能相等,那么a[1]本身就是一种排列方式了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10,INF=1e8;
ll a[N],b[N],n;
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n;i++)
scanf("%lld",&a[i]);
b[1] = a[1];
ll z = 0, f = 0,ans=0;
for (int i = 2; i <= n;i++)
{
b[i] = a[i] - a[i - 1];
if(b[i]>0)
z += b[i];
else
f -= b[i];
}
ans += min(z, f)+abs(z-f);
printf("%lld\n%lld", ans, abs(f - z) + 1);
return 0;
}
AcWing 101. 最高的牛
思路:如果两头牛要相互看的见的话它们之间的牛的身高必须都小于他们,于是我们对每次输入的牛让它们之间的牛身高都-1,利用差分数组记录一下每对牛之间的相对关系,最后转化成前缀和再加上最高的牛的身高。
一开始判重用的是int数组结果超内存了,改用map就过了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int N=1e4+10,INF=1e8;
map<pair<int, int>,int> mp;
int ans[N];
int main()
{
int n, p, h, m;
scanf("%d%d%d%d", &n, &p, &h, &m);
for (int i = 1; i <= m;i++)
{
int a, b;
scanf("%d%d", &a, &b);
if(a>b)
swap(a, b);
if(mp[{a,b}])
continue;
mp[{a,b}] = 1;
ans[a + 1]--;
ans[b]++;
}
for (int i = 1; i <= n;i++)
{
ans[i] +=ans[i-1];
printf("%d\n", ans[i]+h);
}
return 0;
}
AcWing 102. 最佳牛围栏
思路:要求平均值*1000,应该用浮点数二分,为了简便计算,对于每个数我们都先减去二分的平均值,这下问题可以转化成在一个序列中求长度不超过L的非负子段和。因为每块地最多也就只有2000头牛,假设每块地都有2000头牛的话,那么二分答案的最大值也就是2000,因此可以缩小二分的范围,在二分的过程中,我们不必枚举每次的最小值,只需要在i增长的过程中记录下当前的最小值就可以,同时不断更新答案:b[i]-mmin。
一开始减平均值的时候想错了,没在二分的时候减。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10,INF=1e8;
int n, m;
double a[N], b[N];
int check(double mid)
{
double mmin = INF, mmax = -INF;
for (int i = 1; i <= n;i++)
b[i] = b[i - 1] + a[i] - mid;
for (int i = m; i <= n;i++)
{
mmin = min(mmin, b[i - m]);
mmax = max(mmax, b[i] - mmin);
}
return mmax >= 0;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n;i++)
{
scanf("%lf", &a[i]);
}
double l = 0, r = 2000;
while(r-l>1e-5)
{
double mid = (l + r) / 2;
if(check(mid))
l = mid;
else
r = mid;
}
printf("%d", int(r * 1000));
return 0;
}
标签:int,mid,long,ans,INF,include,2022.3 来源: https://www.cnblogs.com/menitrust/p/15977432.html