7.5.实验 解题参考
2016-07-05 11:28
232 查看
Problem-A(HDU1157)
排序水题,将输入数据排序用一次sort,输出中位数即直接输入第n/2个位置上的数。
Problem-B(HDU1106)
这一题排序的部分很简单,将原串预处理分开,并逐一转换成数字,对这些数字sort一遍就可以输出了。
但是原串的预处理分割有点麻烦,需要考虑完备5出现的情况。
这里给出几组测试样例,这些都过了基本就考虑完全了:
555556 //开头有5的
1555556 //中间有一堆5的
125 //5结尾的
55552345891 //不是5结尾的
1234 //没有5的
12345531232 //不是5结尾的
每次遍历原串的每个位置,根据是否是5、出现5时位置与周边的情况决定分割。具体处理见标程。
Problem-C(HDU1031)
这一题需要做两趟排序,第一趟是对计算出的总满意度降序,排过之后可以确定能取到的前k项,但输出要求按编号降序,所有对前k个元素又要按条件再排序一次。
注意为排序方便,每个元素应该构造一个结构体,记录其总满意度和其编号。第一次排序对所有元素,所以范围是【a,a+m】,第二次是取前k个,所有范围是【a,a+k】。两次排序条件不一样,必须要自己写出两个比较函数(cmp1、cmp2)。
Problem-D
这道题有必要说一下题目大意了,稍有不慎就绕晕了TAT
题目大意:给你n个0~200之间的数,每个数对应有一个函数值,若所有的函数值出现的频率都相等而自变量不相等时是Bad,否则输出频率最高的函数值,若有多个升序输出。
前期处理很好做,就是输入一个数,将其转换为函数值存起来。
然后排序
4000
就好,但排完后是要看频率最高而不是当前数字大小。
那么可以对排好的顺序数组加个标签,相同的数排在一起正好可以累计计数,即每组相同的数最后一个的标记数出了其出现的总个数。
有了这个计数,找频率最高也就是找计数最大,引进一个变量m更新就好。
但可能有Bad的情况,那么再引进一个变量sm数出关联最大频率(一会可能要输出)的数的个数。如果最后它等于n,那么小心了,这说明所有函数值出现频率相等,肯是Bad。
为什么以上情况不能直接确定Bad呢(这也是我WA到落泪的地方),注意题意,频率都相同但数值有不相同才Bad,否则照常输出的。
所有可以通过刚刚的标记数组,看最后一个计数标记,若累计为n说明数字全一样,照常输出,多累计不为n才说明数值有不同的,所以符合(sm==n && num[n-1]!=n)的才是Bad情况。
出去Bad的情况,直接输出就很好输出了,从头到尾找一遍,如果标记计数等于最大值m,就是要输出的元素,为了调整换行格式,需要提前倒着找到最后一个,这是常见的输出小技巧。
具体见程序。
排序水题,将输入数据排序用一次sort,输出中位数即直接输入第n/2个位置上的数。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int a[10010]; int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); printf("%d\n",a[n/2]); } return 0; }
Problem-B(HDU1106)
这一题排序的部分很简单,将原串预处理分开,并逐一转换成数字,对这些数字sort一遍就可以输出了。
但是原串的预处理分割有点麻烦,需要考虑完备5出现的情况。
这里给出几组测试样例,这些都过了基本就考虑完全了:
555556 //开头有5的
1555556 //中间有一堆5的
125 //5结尾的
55552345891 //不是5结尾的
1234 //没有5的
12345531232 //不是5结尾的
每次遍历原串的每个位置,根据是否是5、出现5时位置与周边的情况决定分割。具体处理见标程。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; char s[10010]; int a[10010]; int change(string s)//将字符串转换成数字 { int len = s.length(); int sum = 0; for(int i = len - 1, j = 0; i >= 0; --i, ++j) sum += (int)(s[i] - '0') * pow(10.0, j); return sum; } int main() { int len, num; string ans; while(scanf("%s", s) != EOF) { len = strlen(s); num = 0; ans = ""; for(int i = 0; i < len; ++i) { if(s[i] != '5') { ans += s[i]; if(i == len - 1) //不是5结尾的 a[num++] = change(ans); } else if(s[i] == '5' && s[i - 1] != '5' && i != 0) //是5且不能一堆5且5不能为第一个 { a[num++] = change(ans); ans = ""; } } sort(a, a + num); for(int i = 0; i < num - 1; ++i) printf("%d ", a[i]); printf("%d\n", a[num - 1]); } return 0; }
Problem-C(HDU1031)
这一题需要做两趟排序,第一趟是对计算出的总满意度降序,排过之后可以确定能取到的前k项,但输出要求按编号降序,所有对前k个元素又要按条件再排序一次。
注意为排序方便,每个元素应该构造一个结构体,记录其总满意度和其编号。第一次排序对所有元素,所以范围是【a,a+m】,第二次是取前k个,所有范围是【a,a+k】。两次排序条件不一样,必须要自己写出两个比较函数(cmp1、cmp2)。
#include<iostream> #include<algorithm> using namespace std; struct stu { double m; int k; }; int cmp1(stu a,stu b) { if(a.m!=b.m) return a.m>b.m; else return a.k<b.k; } int cmp2(stu a,stu b) { return a.k>b.k; } int main() { int n,m,k; double b; int i; stu s[10000]; while(cin>>n>>m>>k) { for(i=0;i<10000;i++) s[i].m=0; while(n--) { for(i=0;i<m;i++) { cin>>b; s[i].m+=b; s[i].k=i; } } sort(s,s+m,cmp1); sort(s,s+k,cmp2); for(i=0;i<k;i++) { cout<<s[i].k+1; if(i<k-1) cout<<' '; } cout<<endl; } return 0; }
Problem-D
这道题有必要说一下题目大意了,稍有不慎就绕晕了TAT
题目大意:给你n个0~200之间的数,每个数对应有一个函数值,若所有的函数值出现的频率都相等而自变量不相等时是Bad,否则输出频率最高的函数值,若有多个升序输出。
前期处理很好做,就是输入一个数,将其转换为函数值存起来。
然后排序
4000
就好,但排完后是要看频率最高而不是当前数字大小。
那么可以对排好的顺序数组加个标签,相同的数排在一起正好可以累计计数,即每组相同的数最后一个的标记数出了其出现的总个数。
有了这个计数,找频率最高也就是找计数最大,引进一个变量m更新就好。
但可能有Bad的情况,那么再引进一个变量sm数出关联最大频率(一会可能要输出)的数的个数。如果最后它等于n,那么小心了,这说明所有函数值出现频率相等,肯是Bad。
为什么以上情况不能直接确定Bad呢(这也是我WA到落泪的地方),注意题意,频率都相同但数值有不相同才Bad,否则照常输出的。
所有可以通过刚刚的标记数组,看最后一个计数标记,若累计为n说明数字全一样,照常输出,多累计不为n才说明数值有不同的,所以符合(sm==n && num[n-1]!=n)的才是Bad情况。
出去Bad的情况,直接输出就很好输出了,从头到尾找一遍,如果标记计数等于最大值m,就是要输出的元素,为了调整换行格式,需要提前倒着找到最后一个,这是常见的输出小技巧。
具体见程序。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int a[1000000],num[1000000]; int main() { int T,t,n,m,sm,x; scanf("%d",&T);t=0; while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&x); a[i]=10000-(100-x)*(100-x); } sort(a,a+n); for(int i=0;i<n;i++) num[i]=1; for(int i=1;i<n;i++) if(a[i]==a[i-1]) num[i]=num[i-1]+1; m=0;sm=0; for(int i=0;i<n;i++) if(num[i]>m){m=num[i];sm=num[i];} else if(num[i]==m) sm+=num[i]; t++;printf("Case #%d:\n",t); if(sm==n && num[n-1]!=n) printf("Bad Mushroom\n"); else { int j=n-1; while(num[j]!=m) j--; for(int i=0;i<j;i++) if(num[i]==m) printf("%d ",a[i]); printf("%d\n",a[j]); } } return 0; }
相关文章推荐
- 在命令行用 sort 进行排序
- 文件遍历排序函数
- 关于C#中排序函数的总结
- C#选择排序法实例分析
- C#插入法排序算法实例分析
- C#实现Datatable排序的方法
- MYSQL必知必会读书笔记第五章之排序检索数据
- SQLSERVER的排序问题结果不是想要的
- Ruby实现插入排序算法及进阶的二路插入排序代码示例
- Windows Powershell排序和分组管道结果
- C#通过IComparable实现ListT.sort()排序
- C#选择法排序实例分析
- SQL学习笔记四 聚合函数、排序方法
- C#对list列表进行随机排序的方法
- jQuery拖动元素并对元素进行重新排序
- 将MySQL查询结果按值排序的简要教程
- 经典排序算法之冒泡排序(Bubble sort)代码
- 一根网线内的8根线哪4根是传输数据的,哪四根是防干扰的
- 在ASP.NET 2.0中操作数据之二十四:分页和排序报表数据
- C语言实现选择排序、冒泡排序和快速排序的代码示例