PAT-A 1044. Shopping in Mars (25)
来源:互联网 发布:模具编程软件 编辑:程序博客网 时间:2024/06/17 05:30
题目链接在此。
这里在《算法笔记》中归类的二分查找当中,但是目前的题解不是二分法的思路。
题意
给出一个整数n和一个整数pay,然后给出n个整数,在这n个整数中找到所有连续的整数使得这些个连续的整数的和等于pay,如果没有这样的整数序列,则找到大于pay且最接近pay的这样的整数序列。下标从1开始。
思路
暴力枚举求解的方法是最容易想到的,即i从1开始枚举,然后j从1开始枚举。但是这种方法会有三个测试点超时。
后来看了《算法笔记》,里面用的二分的做法,虽然也比较好理解,但是我感觉这种做法虽然有三个测试点超时,但是在细节上修改一下应该能AC,后来在网上找了,也的确看到了相应的题解记录,比如这个。
所谓细节上的优化是指:
1. 输入数据的存储上,使用数组保存前i项的和,而不是第i项,即sum[i]=j表示从第1项到第i项的和为j,这样就省去了求前i项和的时间。
2. 当找到了一组序列和大于或等于pay的序列,马上退出j循环,因为下面找到的一定是比这组的序列和要大的序列,不需要继续找下去。
3. 当j循环已经到了n,还没找到符合的条件的序列,则可以跳出所有循环,输出已经保存在ans数组中的信息了。因为j到了n了还没找到符合条件的序列,i++之后的序列和只能更小,也是没有必要再找下去了。
以上就可以通过。不过输入输出需要用printf和scanf,用cin&cout貌似会有一个点超时。
AC代码
#include<cstdio>#include<cstring>using namespace std;int n; int pay;int sum[100010];int index1 = 0; //控制ans数组的小标,不用index是因为和c++的关键字重复 int ans[100010][2]; //保存刚好大于pay的序列的下标上下界 int min = 100000010; int main(){ scanf("%d %d",&n, &pay); sum[0] = 0; for(int i = 1; i <= n; i++){ scanf("%d",&sum[i]); sum[i] += sum[i-1]; } int i,j ; bool flag = false; //用来标记是否有序列和等于pay的序列,有的话flage = true for(i = 1; i <= n; i++) { j = i; while(j <= n){ int s = sum[j] - sum[i-1]; if( s >= pay){ //找到了符合条件的序列 if(s == pay){ //序列和等于pay printf("%d-%d\n",i,j); //直接输出 flag = true; //设置标志位 }else{ //s > pay if(s < min){ //如果s比当前序列和最小的那个序列还小 index1 = 0; //,则覆盖掉之前的 min = s; ans[index1][0] = i; ans[index1][1] = j; index1++; } else if(s == min){ // s和当前序列和最小的那个序列一样大 min = s; ans[index1][0] = i; //则保存进ans数组 ans[index1][1] = j; index1++; } } break; } j++; } if(j > n) break; } if(flag == false){ //如果没有序列和等于pay的序列 for(int i = 0; i < index1; i++){ //则输出序列和刚好大于pay的序列 printf("%d-%d\n",ans[i][0],ans[i][1]); } } return 0;}
由于s==pay的情况会是s>=pay的情况中最小的那个,所以也可以将两种情况结合起来,写成如下这样。
#include<cstdio>#include<cstring>using namespace std;int n; int pay;int sum[100010];int index1 = 0; //控制ans数组的小标,不用index是因为和c++的关键字重复 int ans[100010][2]; //保存刚好大于pay的序列的下标上下界 int min = 100000010; int main(){ scanf("%d %d",&n, &pay); sum[0] = 0; for(int i = 1; i <= n; i++){ scanf("%d",&sum[i]); sum[i] += sum[i-1]; } int i,j ; for(i = 1; i <= n; i++) { j = i; while(j <= n){ int s = sum[j] - sum[i-1]; if( s >= pay){ //找到了符合条件的序列 if(s < min){ //如果s比当前序列和最小的那个序列还小 index1 = 0; //,则覆盖掉之前的 min = s; ans[index1][0] = i; ans[index1][1] = j; index1++; } else if(s == min){ // s和当前序列和最小的那个序列一样大 min = s; ans[index1][0] = i; //则保存进ans数组 ans[index1][1] = j; index1++; } break; } j++; } if(j > n) break; } for(int i = 0; i < index1; i++){ //则输出序列和刚好大于pay的序列 printf("%d-%d\n",ans[i][0],ans[i][1]); } return 0;}
0 0
- PAT A 1044. Shopping in Mars (25)
- PAT(A) - 1044. Shopping in Mars (25)
- PAT(A) - 1044. Shopping in Mars (25)
- PAT-A 1044. Shopping in Mars (25)
- PAT-A-1044. Shopping in Mars (25)
- 1044. Shopping in Mars (25)-PAT
- PAT 1044. Shopping in Mars (25)
- PAT 1044. Shopping in Mars (25)
- PAT 1044. Shopping in Mars (25)
- PAT 1044. Shopping in Mars (25)
- 【PAT】1044. Shopping in Mars (25)
- [pat]1044. Shopping in Mars (25)
- PAT 1044. Shopping in Mars (25)
- 【PAT甲级】1044. Shopping in Mars (25)
- PAT甲级.1044. Shopping in Mars (25)
- 1044. Shopping in Mars (25) PAT 甲级
- PAT甲级1044. Shopping in Mars (25)
- PAT 1044. Shopping in Mars (25)
- P1801 黑匣子(对顶堆)
- HDU1584~蜘蛛牌(深搜)
- 剑指offer_12(打印出从1到最大n位数)
- C++ 类模板声明时注意的地方
- maven项目使用maven-assembly-plugin打包成可运行的jar
- PAT-A 1044. Shopping in Mars (25)
- Unity 网格合并
- opencv调用是视频图像并且显示
- 防止一个按钮在单位时间内提交多次
- event-config.h指明所在系统的环境
- 继承的实现与限制
- hive空值判断
- [C++学习]剑指offer8题学习笔记
- android 6.0在关机界面添加截图功能