Phone List 字典序

来源:互联网 发布:windows 路由表 命令 编辑:程序博客网 时间:2024/05/16 11:02

Phone List

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8099    Accepted Submission(s): 2766


Problem Description
Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone catalogue listed these numbers:
1. Emergency 911
2. Alice 97 625 999
3. Bob 91 12 54 26
In this case, it’s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob’s phone number. So this list would not be consistent.
 

Input
The first line of input gives a single integer, 1 <= t <= 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 <= n <= 10000. Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.
 

Output
For each test case, output “YES” if the list is consistent, or “NO” otherwise.
 

Sample Input
2391197625999911254265113123401234401234598346
 




做ACM题的时候,排序是一种经常要用到的操作。如果每次都自己写个冒泡之类的O(n^2)排序,不但程序容易超时,而且浪费宝贵的比赛时间,还很有可能写错。STL里面有个sort函数,可以直接对数组排序,复杂度为n*log2(n)。使用这个函数,需要包含头文件 #include <algorithm>


       这个函数可以传两个参数或三个参数。第一个参数是要排序的区间首地址,第二个参数是区间尾地址的下一地址。也就是说,排序的区间是[a,b)。简单来说,有一个数组int a[100],要对从a[0]到a[99]的元素进行排序,只要写sort(a,a+100)就行了,默认的排序方式是升序
       拿我出的“AC的策略”这题来说,需要对数组t的第0到len-1的元素排序,就写sort(t,t+len);
   对向量v排序也差不多,sort(v.begin(),v.end());
   排序的数据类型不局限于整数,只要是定义了小于运算的类型都可以,比如字符串类string
   如果是没有定义小于运算的数据类型,或者想改变排序的顺序,就要用到第三参数——比较函数。比较函数是一个自己定义的函数,返回值是bool型,它规定了什么样的关系才是“小于”。想把刚才的整数数组按降序排列,可以先定义一个比较函数cmp
bool cmp(int a,int b)
{
    return a>b;
}
  排序的时候就写sort(a,a+100,cmp);

  假设自己定义了一个结构体node
struct node{
    int a;
    int b;
    double c;
}
  

 

有一个node类型的数组node arr[100],想对它进行排序:先按a值升序排列,如果a值相同,再按b值降序排列,如果b还相同,就按c降序排列。就可以写这样一个比较函数:

以下是代码片段:
bool cmp(node x,node y)
{
     if(x.a!=y.a) return x.a<y.a;

     if(x.b!=y.b) return x.b>y.b;
     return x.c>y.c;
}
    

排序时写sort(arr, arr+100, cmp);


===================qsort用法=====================

语法:

   #include <stdlib.h>  void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );功能: 对buf 指向的数据(包含num 项,每项的大小为size)进行快速排序。如果函数compare 的第一个参数小于第二个参数,返回负值;如果等于返回零值;如果大于返回正值。函数对buf 指向的数据按升序排序。 

============

上面说的很抽象,其实概括起来就是,比较函数的参数相减顺序如果一样就是升序(从小到大),如果相反就是降序(从大到小)。例如下面的cmp()就是升序,但如果函数体改写成return *(int *)b-*(int *)a;就是降序了,很简单吧!


qsort(s[0],n,sizeof(s[0]),cmp);

int cmp(const void *a, const void *b)
{
    return *(int *)a-*(int *)b;
}

 

一、对int类型数组排序  

int num[100];  

Sample:  

int cmp ( const void *a , const void *b )  
{
  
return *(int *)a - *(int *)b;
  
}
  

qsort(num,100,sizeof(num[0]),cmp);  

二、对char类型数组排序(同int类型)  

char word[100];  

Sample:  

int cmp( const void *a , const void *b )  
{
  
return *(char *)a - *(int *)b;
  
}
  

qsort(word,100,sizeof(word[0]),cmp);  

三、对double类型数组排序(特别要注意)  

double in[100];  

int cmp( const void *a , const void *b )  
{  
      return *(double *)a > *(double *)b ? 1 : -1;  
}  

qsort(in,100,sizeof(in[0]),cmp)  

四、对结构体一级排序  

struct In  
{
  
double data;
  
int other;
  
}s[100]
  

//按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种,参考上面的例子写  

int cmp( const void *a ,const void *b)  
{
  
return ((In *)a)->data - ((In *)b)->data ;
  
}
  

qsort(s,100,sizeof(s[0]),cmp);  

五、对结构体 

struct In  
{
  
int x;
  
int y;
  
}s[100];
  

//按照x从小到大排序,当x相等时按照y从大到小排序  

int cmp( const void *a , const void *b )  
{
  
struct In *c = (In *)a;
  
struct In *d = (In *)b;
  
if(c->x != d->x) return c->x - d->x;
  
else return d->y - c->y;
  
}
  

qsort(s,100,sizeof(s[0]),cmp);  

六、对字符串进行排序  

struct In  
{
  
int data;
  
char str[100];
  
}s[100];
  

//按照结构体中字符串str的字典顺序排序  

int cmp ( const void *a , const void *b )  
{
  
return strcmp( ((In *)a)->str , ((In *)b)->str );
  
}
  

qsort(s,100,sizeof(s[0]),cmp);  

七、计算几何中求凸包的cmp  

intcmp(const void *a,const void *b) //重点cmp函数,把除了1点外的所有点,旋转角度排序  
{
  
struct point *c=(point *)a;
  
struct point *d=(point *)b;
  
if( calc(*c,*d,p[1]) < 0) return 1;
  
else if( !calc(*c,*d,p[1]) && dis(c->x,c->y,p[1].x,p[1].y) <dis(d->x,d->y,p[1].x,p[1].y)) //
如果在一条直线上,则把远的放在前面  
return 1;
  
else return -1;
  
}




这个题的关键是给这些电话号码排个字典序,排好之后,直接比较相邻的两串是否存在前缀问题,
比如说 
911
97625999
91125426
这组数据,按字典序拍好后是
911
91125426
97625999
按着这个顺序进行比较就可得出结果


所以关键是弄这个字典序,可以通过sort函数排字典序,
如果用二维数组做 sort 函数不好用,还得自己写比较函数,
但是sort可直接对string类排字典序
所以直接定义 string tel[N] 来做

#include<iostream>#include<algorithm>#include<string>#define N 10010using namespace std;string tel[N]; bool judge(int n){    int i,k,len;    for(k=0;k<n-1;k++)    {        len=tel[k].size();        for(i=0;i<len;i++)             if(tel[k][i]!=tel[k+1][i])                break;        if(i==len) return true;    }    return false;} int main(){    int t,i,n;    cin>>t;    while(t--)    {       cin>>n;        for(i=0;i<n;i++) cin>>tel[i];        sort(tel,tel+n);        if(judge(n))cout<<"NO"<<endl;        else cout<<"YES"<<endl;    }    return 0;}



原创粉丝点击