题目链接:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=3524&cid=1741
友谊的小船
Time Limit: 1000MS Memory limit: 65536K
题目描述
小铜和小银共同乘坐在友谊的小船上,坐的时间久了,小铜就十分地想撩小银,可是矜持的小银十(ji)分(qi)不(ke)想(wang)让小铜撩他,于是他给小铜出了一道题,如果小铜能够得出正确答案,他们的小船便会升华成基情的巨轮,否则,友谊的小船说翻就翻哦。
问题是这样的:
给定n个整数(A1,A2,A3...Ai...An)从左往右按顺序写成一行,要求从第1个数字A1出发开始选,选数字的规则是这样的:
如果当前选择了第i个数字,那么下一步只能选择第i*2个数字或第i*2+1个数字,依次类推不断地选数字直至没有数字可选为止,然后是这样的:
按照某条选数字路径把所选数字累加起来(当然有好多种选数字路径),会得到一个累加和,求可能得到的累加和中的最小的正整数。
问题是这样的:
给定n个整数(A1,A2,A3...Ai...An)从左往右按顺序写成一行,要求从第1个数字A1出发开始选,选数字的规则是这样的:
如果当前选择了第i个数字,那么下一步只能选择第i*2个数字或第i*2+1个数字,依次类推不断地选数字直至没有数字可选为止,然后是这样的:
按照某条选数字路径把所选数字累加起来(当然有好多种选数字路径),会得到一个累加和,求可能得到的累加和中的最小的正整数。
输入
多组输入,对于每组输入第一行有一个n(1 <= n <= 10^5),代表整数的数量。
第二行有n个空格间隔的整数A1 A2 A3...Ai...An(|Ai| <= 1000),代表n个整数。
第二行有n个空格间隔的整数A1 A2 A3...Ai...An(|Ai| <= 1000),代表n个整数。
输出
对于每组输入输出一个整数,代表所有可能的累加和之中的最小的正整数(PS:0不是正整数)。
如果找不到这个最小正整数,则输出"Excuse me?"(输出不包含引号)。
如果找不到这个最小正整数,则输出"Excuse me?"(输出不包含引号)。
示例输入
5 1 2 3 4 5 7 1 2 3 -4 1 -2 -1 4 1 2 -1 -4
示例输出
4 2 Excuse me?
提示
来源
Shannon
示例程序
第一次写博客,在校集训队可能算是比较晚的了,但是已经下定决心要做好ACM(受到了很大的刺激。。),就先拿这道前几天机试的水题写一下吧!
题目描述算是比较啰嗦的了,简单来说就是给定n个整数(A1,A2,..An),从第一个数(假设下标为i)开始往后选择第i*2或第i*2+1个数(如果存在的话),直到i*2>n并且i*2+1>n停止,然后计算可能得到的累加和中的最小的正整数。
算是裸的dfs了吧,当时比赛的时候这道题居然没有几个人过233,啰嗦的题面瞬间吓退了很多人,然而我也是被前面的几道不明题意的大水题给困住导致后边这几道能做出来的没做完,也有一点时间的因素吧,平时比赛都是3个小时,这次只有一个半,平时就做题马马虎虎改半天才A的我做成这样也不为奇了吧
废话不多说,直接上代码:
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- int m, n, a[1000005];
- void dfs(int x, int ans)//ans记录x对应的和,这里最好是别用全局变量
- {
- if(x*2>n&&x*2+1>n&&ans>0&&ans<m) //x*2>n&&x*2+1>n时更新m
- m=ans;
- if(x*2<=n)
- dfs(2*x,ans+a[x*2]);
- if(x*2+1<=n)
- dfs(2*x+1,ans+a[x*2+1]);
- return ;
- }
- int main()
- {
- while(~scanf("%d", &n))
- {
- m=99999999;
- for(int i=1;i<=n;i++)
- scanf("%d", &a[i]);
- dfs(1,a[1]);
- if(m!=99999999)
- printf("%d\n", m);
- else printf("Excuse me?\n"); //m==99999999表明最小值不为正整数
- }
- return 0;
- }