B. Fence(前缀和)
题意:输入一个数n(篱笆),再输入一个k(指的一个区间,从i到i+k-1),再输入n个数 ai(在题中指的篱笆的高度),题中要求找到和最小的区间,并输出该区间的左端点。
题解:这道题是用前缀和,暴力是不可能暴力了。首先,要想找到和最小的区间,最好是能够直接得到对应区间的和,这时候就要想到前缀和了。将输入的a[i]以及a[i]以前的和都储存起来,这样当需要某个区间的值的时候就可以直接dp[i]-dp[i-k],得到相应区间的和。(当然也可以直接把和算到a[i]里,输入一个加一个,同样不会影响)。注意数组开得太大,容易爆数组,建议放在main函数外面。
ACcode:
int n, k,pos, a[150010], dp[150100];
int main()
{
memset(a, 0, sizeof(a));
memset(dp, 0, sizeof(dp));
cin >> n >> k;
for (int i = 0; i < n; i++)
cin >> a[i];
dp[0] = a[0];
for (int i = 1; i < n; i++)
dp[i] += a[i]+dp[i-1];//这是前缀和
int minn = 0xfffffff;//一种无穷大的写法
for(int i=k-1;i<n;i++)//需要从k-1开始
{
if (minn > dp[i] - dp[i - k])//找到和最小的区间,保存对应的左端点
{
minn = dp[i] - dp[i - k];
pos = i-(k-1)+1;
}
}
cout << pos;
return 0;
}