坑点:accept和deny的ip可能相同,需加个判断
#include <cstdio> #include <cstdlib> #include <vector> #include <string> #include <cstring> #include <iostream> #define OO 0x0fffffff #define MIN(a,b) (a<b?a:b) using namespace std; struct NODE{ NODE *left,*right; int aid; bool accept; NODE(){ aid = -1; left = right = NULL; } }; NODE root; int digits[4]; void add_acl(int id,char *acl,bool accept){ NODE *ptr = &root; for(int i=0;acl[i];i++){ if(acl[i]=='1') { if(ptr->right==NULL) ptr->right = new NODE(); ptr = ptr->right; } else{ if(ptr->left==NULL) ptr->left = new NODE(); ptr = ptr->left; } } if(ptr->aid<0){ ptr->aid = id; ptr->accept = accept; } } void parse_ip(char *input,char *output,int len){ sscanf(input,"%d.%d.%d.%d",digits+0,digits+1,digits+2,digits+3); int i,j; for(i=0;i<4;i++){ int td = digits[i]; for(j=(i+1)*8-1;j>=i*8;j--){ output[j] = '0'+(td&1); td>>=1; } } output[len]='\0'; } int main(){ int m,n,len; char type[66],str[66],ip[66]; scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ cin>>type>>str; len = 32; std::size_t idx = string(str).find('/'); if(idx!=std::string::npos){ str[idx]='\0'; len = atoi(str+idx+1); } parse_ip(str,ip,len); add_acl(i,ip,type[0]=='a'); } for(int i=0;i<m;i++){ cin>>str; parse_ip(str,ip,32); NODE *ptr = &root; int ans = OO; bool accept = true; int iptr = 0; while(ptr){ if(ptr->aid>=0) { if(ptr->aid<ans){ ans = ptr->aid; accept = ptr->accept; } } if(ip[iptr]=='1') ptr=ptr->right; else ptr=ptr->left; iptr++; } puts(accept?"YES":"NO"); } return 0; }