题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1263
Problem Description
夏天来了~~好开心啊,呵呵,好多好多水果~~ Joe经营着一个不大的水果店.他认为生存之道就是经营最受顾客欢迎的水果.现在他想要一份水果销售情况的明细表,这样Joe就可以很容易掌握所有水果的销售情况了.
Input
第一行正整数N(0<N<=10)表示有N组测试数据. 每组测试数据的第一行是一个整数M(0<M<=100),表示工有M次成功的交易.其后有M行数据,每行表示一次交易,由水果名称(小写字母组成,长度不超过80),水果产地(小写字母组成,长度不超过80)和交易的水果数目(正整数,不超过100)组成.
Output
对于每一组测试数据,请你输出一份排版格式正确(请分析样本输出)的水果销售情况明细表.这份明细表包括所有水果的产地,名称和销售数目的信息.水果先按产地分类,产地按字母顺序排列;同一产地的水果按照名称排序,名称按字母顺序排序. 两组测试数据之间有一个空行.最后一组测试数据之后没有空行.
Sample Input
1
5
apple shandong 3
pineapple guangdong 1
sugarcane guangdong 1
pineapple guangdong 3
pineapple guangdong 1
Sample Output
guangdong
|----pineapple(5)
|----sugarcane(1)
shandong
|----apple(3)
解题思路:这道题的要求就是相同产地归为一类,相同水果进行计数,且输出是按字典序输出的。很基础的题目。怎么处理相同产地相同种类的水果数呢?我的做法就是如果当前的记录与下一条记录有相同的产地和相同的某种水果,就将这条记录的num计数存放到下一个记录中,同时将这条记录的num赋值为0,当比较到与下一个不相同的时候就先输出当前的产地,然后从前往当前遍历,如果产地相同,且num不为0,即可输出当前产地某种水果的总数量。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct node 4 { 5 char fruit[81];//水果名称 6 char area[81];//产地名称 7 int num;//交易次数 8 }c[101]; 9 bool cmp(node x,node y)//排序规则 10 { 11 if(strcmp(x.area,y.area)<0)return true;//产地先从小到大排序 12 if(strcmp(x.area,y.area)==0 && strcmp(x.fruit,y.fruit)<0)return true;//如果产地相同,则按照字典将水果排序 13 return false;//否则返回假 14 } 15 int main() 16 { 17 int N,M; 18 cin>>N; 19 while(N--){ //测试数据组数 20 cin>>M; 21 getchar(); //吃掉回车符 22 for(int i=0;i<M;i++)//M次交易 23 cin>>c[i].fruit>>c[i].area>>c[i].num; 24 sort(c,c+M,cmp);//按规则排序 25 for(int i=0;i<M;i++){ 26 if(strcmp(c[i].area,c[i+1].area)==0){//如果当前产地与下一个产地相同 27 if(strcmp(c[i].fruit,c[i+1].fruit)==0){//且水果名称相同 28 c[i+1].num+=c[i].num;//则将水果数目进行相加 29 c[i].num=0;//将原来的水果数目清空 30 } 31 } 32 else{//如果不同 33 cout<<c[i].area<<endl;//不同就先输出产地 34 for(int j=0;j<M;j++){//依次再进行比较 35 if(strcmp(c[i].area,c[j].area)==0 && c[j].num)//找到一个num是不为0的,即该产地某种水果的总数 36 cout<<" |----"<<c[j].fruit<<‘(‘<<c[j].num<<‘)‘<<endl;//输出最后的水果数 37 } 38 } 39 } 40 if(N!=0)cout<<endl;//案例之间输出空行 41 } 42 return 0; 43 }
下面是string版本:
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct node 4 { 5 string fruit;//水果名称 6 string area;//产地名称 7 int num;//交易次数 8 }c[101]; 9 bool cmp(node x,node y)//排序规则 10 { 11 if(x.area!=y.area)return x.area<y.area;//产地先从小到大排序 12 return x.fruit<y.fruit;//如果产地相同,水果按字典排序 13 } 14 int main() 15 { 16 int N,M; 17 cin>>N; 18 while(N--){ //测试数据组数 19 cin>>M; 20 getchar(); //吃掉回车符 21 for(int i=0;i<M;i++)//M次交易 22 cin>>c[i].fruit>>c[i].area>>c[i].num; 23 sort(c,c+M,cmp);//按规则排序 24 for(int i=0;i<M;i++){ 25 if(c[i].area==c[i+1].area){//如果当前产地与下一个产地相同 26 if(c[i].fruit==c[i+1].fruit){//且水果名称相同 27 c[i+1].num+=c[i].num;//则将水果数目进行相加 28 c[i].num=0;//将原来相同水果的数目清空 29 } 30 } 31 else{//如果不同 32 cout<<c[i].area<<endl;//不同就先输出产地 33 for(int j=0;j<M;j++){//依次再进行比较 34 if((c[i].area==c[j].area) && c[j].num)//找到此时水果的最后一个计数num是不为0的,即为该产地某种水果的总数 35 cout<<" |----"<<c[j].fruit<<‘(‘<<c[j].num<<‘)‘<<endl;//输出最后的水果数 36 } 37 } 38 } 39 if(N!=0)cout<<endl;//案例之间输出空行 40 } 41 return 0; 42 }