为学论坛“每日一题”系列---数列操作(我的解法有误)
2013-03-28 18:54
246 查看
原题目链接:http://www.51weixue.com/thread-678-1-1.html
题目:
原来我的解法是错的。。。2 3 3 2,这个序列是可以消去的。。
我的解法,大概就是类似于分治法的思想,将一个数列拆分一个一个小数列,再分别求解:
1、先从简单的几个测试示例找规律,将问题简单化。
当n = 2时,只有两个元素大小相同时,数列才可以变为全0的数列。
当n = 3时,只有当中间元素的大小等于首尾元素大小之和时,数列才可以变为全为的数列。
当n = 4时,可以将这4个元素拆分为两组,也就变成了两个n = 2的情况。所以,可以根据n = 2。
同理,当n = 5时,可以将这5个元素拆分为一个由3个元素组成的小数列和一个由2个元素组成的小数列,再分别求解。
所以当n > 3时,可以将n为解成多个由2个元素和3个元素组成的小数列,然后分别求解,最后合并结果。
一开始是先想到递归解法的,不过既然知道可以拆成由2个元素或者3个元素小数列,那么就可以直接写出非递归解法。
测试数据:
9
1 2 1 4 5 1 2 3 1
5
2 2 3 2 2
8
1 2 1 4 5 1 1 1
6
1 2 1 4 5 1
9
1 2 1 1 1 1 1 1 1
2
2 2
3
4 1 6
4
2 6 4 4
1
4
5
1 1 1 1 1
附上别人的一个更好的思路:
最后一个数只能和倒数第二个数同时消去,倒数第二个和最后一个消去之后,只能和倒数第三个同时消去。
按照这个思路,从最后一个数开始,a[i-1] -= a[i],当i-1!=1且a[i-1] < 0时,无解。最后看a[0]是不是为0,如果为0,则yes,否则为no。
题目:
给定一个长度为n的非负整数序列n<=100000,只能进行一种操作:选择一个数(不是最后一个)把ai和a(i+1)同时减少1。 问能否经过有限次这样的操作把这个数列变为全0的数列。 输入:长度为n的数组 每个数是正整数 输出:yes 或 no |
我的解法,大概就是类似于分治法的思想,将一个数列拆分一个一个小数列,再分别求解:
1、先从简单的几个测试示例找规律,将问题简单化。
当n = 2时,只有两个元素大小相同时,数列才可以变为全0的数列。
当n = 3时,只有当中间元素的大小等于首尾元素大小之和时,数列才可以变为全为的数列。
当n = 4时,可以将这4个元素拆分为两组,也就变成了两个n = 2的情况。所以,可以根据n = 2。
同理,当n = 5时,可以将这5个元素拆分为一个由3个元素组成的小数列和一个由2个元素组成的小数列,再分别求解。
所以当n > 3时,可以将n为解成多个由2个元素和3个元素组成的小数列,然后分别求解,最后合并结果。
一开始是先想到递归解法的,不过既然知道可以拆成由2个元素或者3个元素小数列,那么就可以直接写出非递归解法。
#include<iostream> #include<cstdio> const int N = 100000 ; bool AllToZero(int *A,int n) ; //递归解法 bool All2Zero(int *A ,int n) ; //非递归解法 int main(void) { int i,n ; int A ; freopen("in.txt","r",stdin) ; while(scanf("%d",&n) != EOF) { for(i = 0 ; i < n ; ++i) { scanf("%d",&A[i]) ; } if(true == AllToZero(A,n)) { printf("Yes\n") ; } else { printf("No\n") ; } } return 0 ; } /*递归版本*/ bool AllToZero(int *A,int n) { if(n > 1) { return (A[n-1] == A[n-2] && AllToZero(A,n-2)) || (n-3 >= 0 && A[n-2] == A[n-1] + A[n-3] && AllToZero(A,n-3)); } else if(0 == n) { return true ; } return false ; } /*非递版本*/ bool All2Zero(int *A,int n) { int i = 0 ; while(i < n) { if(i+1 < n && A[i] == A[i+1]) { i += 2 ; } else if(i+1 < n && i+2 < n && A[i+1] == A[i] + A[i+2]) { i += 3 ; } else //一旦发现不能变成0的小数列,立马返回 { return false ; } } return true ; }
测试数据:
9
1 2 1 4 5 1 2 3 1
5
2 2 3 2 2
8
1 2 1 4 5 1 1 1
6
1 2 1 4 5 1
9
1 2 1 1 1 1 1 1 1
2
2 2
3
4 1 6
4
2 6 4 4
1
4
5
1 1 1 1 1
附上别人的一个更好的思路:
最后一个数只能和倒数第二个数同时消去,倒数第二个和最后一个消去之后,只能和倒数第三个同时消去。
按照这个思路,从最后一个数开始,a[i-1] -= a[i],当i-1!=1且a[i-1] < 0时,无解。最后看a[0]是不是为0,如果为0,则yes,否则为no。
相关文章推荐
- 为学论坛“每日一题”系列---最短的包含字符串(待验证正确性)
- Sharepoint学习笔记—ECMAScript对象模型系列-- 4、使用ECMA操作网站对象(website)
- STM32F030系列实现仿位带操作
- 【python系列】set类型的操作
- 秒杀多线程第三篇 原子操作 Interlocked系列函数
- 线段树模板 cogs数列操作c
- 【C#进阶系列】27 I/O限制的异步操作
- 活动目录系列之九:操作主机
- Windows线程(三)原子操作Interlocked系列函数
- redhat操作命令笔记---系列3
- 快乐Python快速上手系列1 - CSV操作
- Android深入浅出系列之Bluetooth—蓝牙操作(一)
- LockWindowUpdate系列3:什么样的操作中应当使用LockWindowUpdate?
- STM系列 Flash操作
- JavaWEB--POI之EXCEL操作、优化、封装详解系列(四)--PoiExportUtil架构设计篇与功能说明
- 敏捷开发智慧敏捷系列之四:每日立会开多久?
- MSDN Visual系列:使用BDC操作来控制业务数据
- MongoDB实战系列之二:MongoDB的常用操作
- 【Linux基本操作】系列02:vim的常用操作