PAT DS 506 航空公司VIP客户查询
2014-10-24 20:14
369 查看
这题时间限制的紧(150ms),导致第一种红黑树的办法最后一个case超时(第二个case用了149ms,汗。。。)。
红黑树的办法就是逐个添加到树里,在ins_update函数里调整,使之符合红黑树规则。具体参见《算法导论》。代码参看附录A。
想到过会不会是strcmp比较费时间,可是简单测试过之后发现,长度为18的字符串之间的strcmp并不比整型数的比较慢多少。见下图(图中数值均为clock_t):
代码参看附录B。
幸好,最后想到应该用hash表来做。便写个简易的hash函数,将身份证号按3,3,4,4,4个数相加,再对10求余,正好10的5次方数量级。代码见附录C。
后记:
粗略算一下的话,红黑树时间复杂度为nlogn数量级,我这个程序大约是n(10+10logn),10^5数据量的话便大约是10^7。加上一条语句大约几个指令,一条指令需要几个到几十个时钟周期,最后便大约是10^8数量级的时钟周期。150ms大约也是10^8时钟周期。CPU是3GHz的话,需要333ms才比较保险,所以是危险的。
附录A:
附录B:
附录C:
红黑树的办法就是逐个添加到树里,在ins_update函数里调整,使之符合红黑树规则。具体参见《算法导论》。代码参看附录A。
想到过会不会是strcmp比较费时间,可是简单测试过之后发现,长度为18的字符串之间的strcmp并不比整型数的比较慢多少。见下图(图中数值均为clock_t):
代码参看附录B。
幸好,最后想到应该用hash表来做。便写个简易的hash函数,将身份证号按3,3,4,4,4个数相加,再对10求余,正好10的5次方数量级。代码见附录C。
后记:
粗略算一下的话,红黑树时间复杂度为nlogn数量级,我这个程序大约是n(10+10logn),10^5数据量的话便大约是10^7。加上一条语句大约几个指令,一条指令需要几个到几十个时钟周期,最后便大约是10^8数量级的时钟周期。150ms大约也是10^8时钟周期。CPU是3GHz的话,需要333ms才比较保险,所以是危险的。
附录A:
<span style="font-size:18px;">#include <stdio.h> #include <assert.h> #include <stdbool.h> #include <string.h> #include <malloc.h> #include <stdlib.h> int n, k, m; typedef struct mem{ char id[19]; long ma; // mileage struct mem *le, *ri, *pa; // left, right, parent bool color; // true if red, false if black }Mem; Mem NIL = {"", 0, NULL, NULL, NULL, false}; Mem *rbtree, *pNIL = &NIL; // red-black tree, .. void insert(char *id, long ma); bool search(char *id, Mem **ppm); int main(void) { #ifdef DEBUG freopen("in.txt", "r", stdin); #endif rbtree = pNIL; scanf("%d%d", &n, &k); int i=0; Mem *pm; for(; i<n; ++i){ char tid[19]; long tma; scanf("%s%ld", tid, &tma); #ifdef DEBUG printf("debug: %s %ld\n", tid, tma); #endif if(tma < k) tma = k; insert(tid, tma); } scanf("%d", &m); for(i=0; i<m; ++i){ char tid[19]; scanf("%s", tid); if(search(tid, &pm)){ assert(pm != pNIL && pm != NULL); #ifdef DEBUG printf("%s: ", pm->id); #endif printf("%ld\n", pm->ma); } else printf("No Info\n"); } return 0; } bool search(char *id, Mem **ppm) { *ppm = rbtree; #ifdef DEBUG printf("\nsearch: %s\n", id); #endif while(*ppm != pNIL){ #ifdef DEBUG printf("%s %ld\n", (*ppm)->id, (*ppm)->ma); #endif int sc = strcmp(id, (*ppm)->id); if(sc == 0) return true; else if(sc < 0) *ppm = (*ppm)->le; else *ppm = (*ppm)->ri; } return false; } void left_rotate(Mem *pm); void right_rotate(Mem *pm); void ins_update(Mem *pm); void insert(char *id, long ma) { Mem *px = rbtree, *py = pNIL; int sc; while(px != pNIL){ py = px; sc = strcmp(id, px->id); if(sc == 0){ px->ma += ma; return; } else if(sc < 0) px = px->le; else px = px->ri; } Mem *pm = (Mem*)malloc(sizeof(Mem)); if(pm == NULL) exit(1); strcpy(pm->id, id); pm->ma = ma; pm->le = pm->ri = pNIL; pm->pa = py; pm->color = true; if(py == pNIL) rbtree = pm; else if(sc < 0) py->le = pm; else py->ri = pm; ins_update(pm); } void ins_update(Mem *z) { Mem *y; while(z->pa->color){ if(z->pa == z->pa->pa->le){ y = z->pa->pa->ri; if(y->color){ z->pa->color = false; y->color = false; z->pa->pa->color = true; z = z->pa->pa; } else{ if(z == z->pa->ri){ z = z->pa; left_rotate(z); } z->pa->color = false; z->pa->pa->color = true; right_rotate(z->pa->pa); } } else{ y = z->pa->pa->le; if(y->color){ z->pa->color = false; y->color = false; z->pa->pa->color = true; z = z->pa->pa; } else{ if(z == z->pa->le){ z = z->pa; right_rotate(z); } z->pa->color = false; z->pa->pa->color = true; left_rotate(z->pa->pa); } } } rbtree->color = false; } void left_rotate(Mem *z) { assert(z != pNIL && z->ri != pNIL); Mem *y = z->ri; z->ri = y->le; if(y->le != pNIL) y->le->pa = z; y->pa = z->pa; if(z->pa == pNIL) rbtree = y; else if(z == z->pa->le) z->pa->le = y; else z->pa->ri = y; y->le = z; z->pa = y; } void right_rotate(Mem *z) { assert(z != pNIL && z->le != pNIL); Mem *y = z->le; z->le = y->ri; if(y->ri != pNIL) y->ri->pa = z; y->pa = z->pa; if(z->pa == pNIL) rbtree = y; else if(z == z->pa->ri) z->pa->ri = y; else z->pa->le = y; y->ri = z; z->pa = y; } </span>
附录B:
<span style="font-size:18px;">#include <stdio.h> #include <string.h> #include <time.h> char id[10000000][19]; int main(void) { clock_t start, finish; long i=0, j; for(i=0; i<10000000; ++i) sprintf(id[i], "%18ld", i); start = clock(); for(i=1; i<10000000; ++i) j = strcmp(id[i], id[i-1]); finish = clock(); printf("strcmp: %ld %ld %ld\n", start, finish, (finish-start)); start = clock(); for(i=1; i<10000000; ++i){ j = id[i][0] > id[i-1][0]; j = id[i][1] > id[i-1][1]; } finish = clock(); printf("long: %ld %ld %ld\n", start, finish, (finish-start)); return 0; }</span>
附录C:
<span style="font-size:18px;">#include <stdio.h> #include <string.h> #include <malloc.h> #include <stdlib.h> int n, k, m; typedef struct s_mem{ char id[19]; long ma; struct s_mem *next; }Mem; Mem *ht[100000]; // hash table long hash(char *id); void insert(char *id, long ma); // mileage int main(void) { #ifdef DEBUG freopen("in.txt", "r", stdin); #endif memset(ht, 0, sizeof(ht)); scanf("%d%d", &n, &k); int i=0; for(i=0; i<n; ++i){ char tid[19]; long tma; scanf("%s%ld", tid, &tma); if(tma < k) tma = k; insert(tid, tma); #ifdef DEBUG printf("\ninsert %s & hash table:\n", tid); long j=0; for(; j<100000; ++j){ Mem *dpm = ht[j]; while(dpm != NULL){ printf("%ld: %s %ld\n", j, dpm->id, dpm->ma); dpm = dpm->next; } } #endif } scanf("%d", &m); for(i=0; i<m; ++i){ char tid[19]; scanf("%s", tid); long h = hash(tid); Mem *pm = ht[h]; while(pm != NULL){ if(strcmp(tid, pm->id)==0){ printf("%ld\n", pm->ma); break; } else pm = pm->next; } if(pm == NULL) printf("No Info\n"); } return 0; } long hash(char *id) { long h = (id[0]+id[1]+id[2])%10*10000; h += (id[3]+id[4]+id[5])%10*1000; h += (id[6]+id[7]+id[8]+id[9])%10*100; h += (id[10]+id[11]+id[12]+id[13])%10*10; h += (id[14]+id[15]+id[16]+id[17])%10; return h; } void insert(char *id, long ma) { long h = hash(id); Mem *pm = ht[h], *pre=ht[h]; while(pm != NULL){ pre = pm; if(strcmp(id, pm->id) == 0){ pm->ma += ma; return; } else pm = pm->next; } if((pm = (Mem*)malloc(sizeof(Mem))) == NULL) exit(1); strcpy(pm->id, id); pm->ma = ma; if(pre != NULL) pre->next = pm; else ht[h] = pm; } </span>
相关文章推荐
- 航空公司VIP客户查询【PAT】
- PAT 航空公司VIP客户查询 (哈希 | map) -- 解题报告
- PAT5-06. 航空公司VIP客户查询
- 航空公司VIP客户查询(25 分)(Hash)
- 航空公司VIP客户查询
- 7-15(查找) 航空公司VIP客户查询(25 分)
- PTA 7-15(查找) 航空公司VIP客户查询(25 分) 25分代码 哈希方法
- PTA-数据结构 5-45 航空公司VIP客户查询 (25分)
- 航空公司VIP客户查询
- PTA 7-45 航空公司VIP客户查询(25 分)map查找应用
- 5-45 航空公司VIP客户查询 (25分)
- PTA 7-15 航空公司VIP客户查询
- 5-45 航空公司VIP客户查询 (25分) HASH
- 客户信息管理系统8—客户信息的模糊查询
- DS | Tree | PAT | Tree Traversals Again
- MVC客户管理(添加、修改、查询、分页)
- 迅雷面试题: 模拟银行一天的工作, 统计vip客户和普通客户的办理业务的平均等待时间.
- Android7.0 Binder通信(3) 客户进程查询和使用服务进程
- PAT DS 3-06 表达式转换
- 对查询出来的记录行进行分页显示,怎么做???在客户现场,哪位大虾帮忙?急急急