区间操作练习
来源:互联网 发布:知乎 pocket 编辑:程序博客网 时间:2024/06/10 01:12
1问题:
允许两个操作,add(min,max)和del(min,max),一开始区间内为空,每个操作后算出区间内的集合,要求能自动合并、拆分集合。例如:
操作1:add(1,7) 区间内的集合:(1,7)
操作2:add(9,10) 区间内的集合:(1,7)、(9,10)
操作3:del(3,5) 区间内的集合:(1,2)、(6,7)、(9,10)
操作4:add(3,8) 区间内的集合:(1,10)
整个区间的范围可能会在(0,2^32-1)之间。
要求给出add()和del()的算法描述和代码实现,程序要实现输入输出即可供用户操作,实现对应命令,统一确定输出命令的格式为
add number1 number2
del number1 number2
stop
比如
add 1 7
(1,7)
del 3 5
(1,2)、(6,7)
stop
程序结束
2.思路
1.因为范围是0到2^32-1,因此直接用int加数据结构来表示区间,至少要用到4*2^32byte的内存空间也就是16G,明显不能这么做
2.在想这是区间操作,又是连续的,区间只有两种状态,一种为空,一种为存在,恰好对应一个位的两种状态,这样就自然而然的想到了用位图的方法,可以
3.既然想到用位图了,就比较好做了,一切水到渠成,首先定义几个位操作的宏函数,然后定义区间操作的宏函数,然后在这个基础上用函数加一些包裹
3.代码如下
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>//思路用位进行操作,每一位代表一个整数#define LEN_8 536870912 //2^32/8#define LEN_32 134217728#define MAX 4294967295 //2^32-1#define MASK 0x1f //5个1unsigned int S[LEN_32]={0};#define set_bit_false(num) S[num>>5]=S[num>>5]&~(1<<(num&31))#define set_bit_true(num) S[num>>5]=(S[num>>5])|(1<<(num&31))#define bit_is_true(num) S[num>>5]&(1<<(num&31))#define hash_bit_true(num1,num2) while(num1<=num2){set_bit_true(num1);num1++;}#define hash_bit_false(num1,num2) while(num1<=num2){set_bit_false(num1);num1++;}void str_aly(char *s,char*fuc,unsigned int* num1,unsigned int* num2);void add(unsigned int num1,unsigned int num2){ hash_bit_true(num1,num2);}void del(unsigned int num1,unsigned int num2){ hash_bit_false(num1,num2);}void print(unsigned int input_max){ unsigned int num=0; unsigned int index1=0,index2=0; int flag=0; while(num<=input_max) { if(bit_is_true(num)&&!flag) { index1=num; flag=1; } else if(bit_is_true(num)&&flag) { index2=num; } else if(!(bit_is_true(num))&&flag) { flag=0; if(index2==0) printf("(%d,%d)\t",index1,index1); else {printf("(%d,%d)\t",index1,index2); } index1=index2=0; } num++; }printf("\n");}void stop(){exit(0);}int main(){ unsigned int input_max=0;unsigned int num1=0,num2=0;//输入的区间 int len=(int)pow(2.0,30)/8; //int len=(int)pow(2,32)-1; // printf("len=%d/n",len); char s[20]; char fuc[30]={'0',}; while(1) {//清空fuc里面的缓存int i=0;for(i=0;i<5;i++){*(fuc+i)=0;} printf("请输入数据\n\t"); gets(s); str_aly(s,fuc,&num1,&num2); if(input_max<num2+1) { input_max=num2+1; } if(strcmp("add",fuc)==0) { add(num1,num2); } else if(strcmp("del",fuc)==0) { del(num1,num2); } else if(strcmp("stop",fuc)==0) { stop(); } else if(strcmp("print",fuc)==0) { print(input_max); } num1=num2=0; //puts(s); } return 0;}void str_aly(char *s,char*fuc,unsigned int* num1,unsigned int* num2){ int flag=1; while(*s) { if(*s!=' '&&flag==1) { *fuc=*s; s++; fuc++; } else if(*s==' '&&flag==1) { flag=2; s++; } else if(*s!=' '&&flag==2) { *num1=*num1*10+*s-'0'; s++; } else if(*s==' '&&flag==2) { flag=3; s++; } else if(*s!=' '&&flag==3) { *num2=*num2*10+*s-'0'; s++; } else if(*s==' '&&flag==3) { break; } }}
0 0
- 区间操作练习
- 区间DP练习
- 线段树练习 区间合并
- 算法练习:重叠区间个数
- 小练习,splay区间反转
- splay区间操作
- 区间/数组操作
- poj-3468 区间操作
- mongoose时间区间操作
- hdu5812 区间操作
- 序列的区间操作
- 【POJ3468】区间操作 Splay
- 线段树区间操作
- Splay 的区间操作
- [CodeVS1082] 线段树练习3(区间修改+询问区间和)
- POJ 3667 splay区间合并练习
- 算法导论14.3区间树 练习总结
- 算法练习-连号区间数
- 廖雪峰python教程笔记01
- YII2自定义公共方法
- 不错的图片压缩技术
- C++中placement new操作符(经典)
- spring mvc 支持options方法
- 区间操作练习
- 关于PreparedStatement.addBatch()方法
- ssm+easyui(框架的搭建)
- php实现基数排序
- cocos-lua 场景切换动画
- bzoj3781 小B的询问【莫队】
- 设计模式--单例模式
- 邮件服务器hMailServer
- HIbernate报should be mapped with insert="false" update="false“错