【前缀和+哈希表】P3131 [USACO16JAN] Subsequences Summing to Sevens S
题目
P3131
分析&&代码
由于模完7之后的数字只有0~6,所以本题的哈希表可以用一个大小为7的数组优化。
原本我写的代码
#include<iostream>using namespace std;const int N = 5e4 + 10;int n,a[N],f[N],mp[10];int main()
{cin >> n;for(int i=1;i<=n;i++) {cin >> a[i];f[i] = (f[i-1] + a[i]) % 7;if(mp[f[i] % 7] == 0) mp[f[i] % 7] = i; //头一次出现,记录下标 }//枚举结尾int ret = 0; for(int i=1;i<=n;i++){ret = max(ret,i-mp[f[i] % 7]);}cout << ret;
}
错误原因:
改正:
#include<iostream>
#include<cstring>using namespace std;const int N = 5e4 + 10;int n,a[N],f[N],mp[10];int main()
{cin >> n;memset(mp,-1,sizeof mp);mp[0] = 0;int ret = 0;for(int i=1;i<=n;i++) {cin >> a[i];f[i] = f[i-1] + a[i];if(mp[f[i] % 7] == -1) mp[f[i] % 7] = i; //头一次出现,记录下标 else ret = max(ret,i-mp[f[i] % 7]);}cout << ret;return 0;
}
优化掉前缀和数组,使用一个int变量sum来代替,因为只用记录一次数值即可,后面不会查。
#include <iostream>
#include <cstring>
using namespace std;const int N = 5e4 + 10;int n, a[N], sum, mp[10];int main()
{cin >> n;memset(mp, -1, sizeof mp);mp[0] = 0;int ret = 0;for (int i = 1; i <= n; i++) {cin >> a[i];sum = (sum + a[i]) % 7;if(mp[sum] == -1) mp[sum] = i;else ret = max(ret,i-mp[sum]);}cout << ret;return 0;
}
使用哈希表的意义就是可以记录下某一个值对应的下标,这样就可以在遍历的过程中用O(1)的时间查找这个值,而不是在遍历的过程中需要查找的时候,还要再来一个for循环把前面的前缀和再遍历一遍看看有没有对应的值。