//题意:题意极其抽象,看这个链接優YoU姐那里有题意以及分析,这里看了她的思路写了代码,并学了用链表创建hash表,虽然过程很曲折,改了好久。这里我发一下我wa的一些情况:1).边界 n=4 k= 4 1 2 4 8; 2)n=1 k= 5 3; 3) n = 1 k = 2 3;主要就这三种
//思路:生成一张hash表然后查找,其中记得有一个思想转换很难,其他就是基础编码了。(刚开始用的动态申请 空间并释放空间)
//50628K 625MS #include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef class node{ public: int idx; class node *next; node(){ next = 0; } }htable; int n, k; htable *hashtable[150000]; int maxlen; int cow[100010][40]; int sum[100010][40]; int c[100010][40]; bool cmp(int l_idx, int n_idx)//l_idx当前这个key下链表中的唯一的值,n_idx传进来的下标 { for(int i = 0; i < k; i++){ if(c[l_idx][i] != c[n_idx][i]) return false; } return true; } void Hash(int i) { //init key int key = 0; //生成键 for(int j = 1; j < k; j++){ //自制生成键的公式 key += c[i][j]; } if(key < 0) key *= -1; key = key%149999; //operate key if(!hashtable[key]){ //若没有该键则生成该键 htable *p = new htable; p -> idx = i; hashtable[key] = p; }else{ htable *pn = hashtable[key]; if(cmp(pn->idx, i)){ //若键值都相同更新最大区间即可,不用添加新的元素进来,每次都是和第一次添加的元素比较 maxlen = (i - (pn -> idx)) > maxlen ? (i - (pn -> idx)) : maxlen; return ; }else{ //若键相同值不同则通过链表生成一个新的值并添加在原有的键上 while(pn -> next){ if(cmp(pn->next->idx, i)){ //若键值都相同更新最大区间即可,不用添加新的元素进来,每次都是和第一次添加的元素比较 maxlen = (i - (pn -> next -> idx)) > maxlen ? (i - (pn -> next -> idx)) : maxlen; //这里注意链表下标idx别写错了改了好久才发现 return ; } pn = pn -> next; } htable* temp = new htable; temp -> idx = i; pn -> next = temp; } } return ; } int main() { while(scanf("%d%d", &n, &k) != EOF){ //init int var; memset(hashtable, 0, sizeof(hashtable)); maxlen = 0; for(int i = 0; i < k+1; i++){ cow[0][i] = 0; sum[0][i] = 0; c[0][i] = 0; } Hash(0); for(int i = 1; i <= n; i++){ scanf("%d", &var); for(int j = 0; j < k; j++){ cow[i][j] = var % 2; sum[i][j] = sum[i-1][j] + cow[i][j]; c[i][j] = sum[i][j] - sum[i][0]; var /= 2; } //hash Hash(i); } printf("%d\n", maxlen); } return 0; }