题意:给定一个序列,问你最多划掉多长的连续序列使得原序列和现序列%m的值相同
解题思路:解这个题有点曲折,c语言中 -3%5 = -3 , 但是题目要求应该是 2,所以在解题的时候出现了问题,这里是有 O(n)的算法的, 利用hash表记录 前i项和 第一次出现某余数的位置,如果这个余数出现过,则可以去除掉 (我们要去掉m的倍数),然后取最长的就可以了。
解题代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <stdlib.h> 5 #include <algorithm> 6 #include <iostream> 7 #include <string> 8 #include <list> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 14 using namespace std; 15 16 //#define DEBUG 17 18 const int maxn = 100000 + 5; 19 20 int dp[maxn]; 21 int hs[maxn]; 22 23 24 int main() 25 { 26 27 int n, m; 28 while (~scanf("%d%d", &n, &m)) 29 { 30 memset(hs,-1,sizeof(hs)); 31 for (int i = 1; i <= n; i++) 32 scanf("%d", &dp[i]); 33 hs[0] = 0; 34 int MAX = 0 ; 35 for (int i = 1; i <= n; i++) 36 { 37 dp[i] += dp[i - 1]; 38 dp[i] %= m; 39 if(dp[i] < 0 ) 40 dp[i] = m + dp[i]; 41 if(hs[dp[i]] != -1) 42 { 43 if(i - hs[dp[i]] > MAX) 44 MAX = i - hs[dp[i]]; 45 } 46 else 47 { 48 hs[dp[i]] = i; 49 } 50 } 51 printf("%d ", MAX); 52 } 53 return 0; 54 }