蓝桥杯-基础算法模板题
1.前缀和&差分
1.1.语文成绩 P2367
#include<bits/stdc++.h>
using namespace std;
const int N=5e6+10;
int m=0x4f4f4f4f;
int d[N];
int a[N];
int n,p,x,y,z;
int main()
{
cin>>n>>p;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) d[i]=a[i]-a[i-1];
for(int i=0;i<p;i++)
{
cin>>x>>y>>z;
d[x]+=z;
d[y+1]-=z;
}
for(int i=1;i<=n;i++)
{
a[i]=d[i]+a[i-1];
if(m>a[i]) m=a[i];
}
cout << m;
return 0;
}
1.2.IncDec Sequence P4552
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=100000+10;
int n;
int a[N];
int d[N];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++) d[i]=a[i]-a[i-1];
int sum1=0;
int sum2=0;
for(int i=2;i<=n;i++)
{
if(d[i]>0) sum1+=d[i];
else sum2-=d[i];
}
cout<<max(sum1,sum2)<<endl<<abs(sum1-sum2)+1<<endl;
return 0;
}
2.二维前缀和&差分
2.1.领地选择 P2004
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int a[N][N];
int main()
{
int n,m,c;
cin>>n>>m>>c;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
}
}
int x=c;
int y=c;
int ans=a[c][c];
for(int i=c;i<=n;i++)
{
for(int j=c;j<=m;j++)
{
int sum=a[i][j]-a[i][j-c]-a[i-c][j]+a[i-c][j-c];
if(sum>ans)
{
ans=sum;
x=i;
y=j;
}
}
}
cout<<x-c+1<<' '<<y-c+1;
return 0;
}
2.2. 地毯P3397
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e3+10;
int a[N][N];
signed main()
{
int n,m,xa,ya,xb,yb;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>xa>>ya>>xb>>yb;
a[xa][ya]++;
a[xb+1][ya]--;
a[xa][yb+1]--;
a[xb+1][yb+1]++;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
cout<<a[i][j]<<' ';
}
cout<<endl;
}
return 0;
}
3.二分答案
3.1. 数列分段 p1182
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],n,m;
bool check(int k,int D)
{
int cnt=0,sum=0;
for(int i=1;i<=n;i++)
{
sum+=a[i];
if(i==n||sum+a[i+1]>k)
{
cnt++;
sum=0;
}
}
return cnt<=D;
}
signed main()
{
cin>>n>>m;
int L=0;
int R=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
L=max(a[i],L);
R+=a[i];
}
while(L<R)
{
int mid=(L+R)>>1;
if(check(mid,m))R=mid;
else L=mid+1;
}
cout<<L<<endl;
return 0;
}
3.2.平均数 P1404
#include <bits/stdc++.h>
#define INF 2147483647
using namespace std;
const int MAXN = 100010;
long long a[MAXN], sum[MAXN];
int n, m;
bool judge(int mid) {
long long Min = INF;
Min *= Min;
for (int i = 1; i <= n; ++i) {
sum[i] = sum[i - 1] + a[i] - mid;
if (i >= m) {
Min = min(Min, sum[i - m]);
if (sum[i] >= Min)
return true;
}
}
return false;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]), a[i] *= 10000;
int l = 0, r = 20000000;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (judge(mid)) l = mid;
else r = mid - 1;
}
if (!judge(l)) --l;
printf("%d\n", l / 10);
return 0;
}
4.双指针
4.1.逛画展 P1638
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10,maxm=2e3+10;
int a[maxn],col[maxm];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
int ansL=1,ansR=n,cnt=0;
for(int l=1,r=0;l<=n&&r<=n;l++)
{
while(cnt<m&&r<n) if(++col[a[++r]]==1) ++cnt;
if(cnt<m)break;
if(cnt==m&&ansR-ansL>r-l)ansL=l,ansR=r;
if(--col[a[1]]==0)--cnt;
}
cout<<ansL<<' '<<ansR;
return 0;
}
5.离散化
5.1.统计数字 P1097
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N],b[N],c[N],d[N];
int k;
int id(int x)
{
return lower_bound(b+1,b+k+1,x)-b;//返回第一个大于等于x的位置
}
signed main()
{
int n,m;
cin>>n,m;
for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
sort(b+1,b+n+1);
k=unique(b+1,b+n+1)-b-1;//排成2 4 5 100 ...剩下的堆在后面,k指向100后面一个数
for(int i=1;i<=n;i++)c[id(a[i])]++;
for(int i=1;i<=1e4;i++)
if(c[i]!=0)
cout<<b[i]<<' '<<c[i]<<endl;
return 0;
}