zoukankan      html  css  js  c++  java
  • 波动数列

    欢迎访问我的新博客:http://www.milkcu.com/blog/

    原文地址:http://www.milkcu.com/blog/archives/2014pa10.html

    引言

    这是2014年第五届蓝桥杯全国软件大赛预赛本科A组(C/C++组)第10题,也就是最后一题。

    思路可以想得到,枚举和广度优先搜索,由于最后时间紧迫,简单的计数还没完成,谨以此文祭奠逝去的蓝桥杯。

    题目描述

    标题:波动数列

        观察这个数列:
        1 3 0 2 -1 1 -2 ...
        这个数列中后一项总是比前一项增加2或者减少3。
        栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?

    【数据格式】
        输入的第一行包含四个整数 n s a b,含义如前面说述。
        输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以100000007的余数。

    例如,输入:
    4 10 2 3
    程序应该输出:
    2

    【样例说明】
    这两个数列分别是2 4 1 3和7 4 1 -2。

    【数据规模与约定】
    对于10%的数据,1<=n<=5,0<=s<=5,1<=a,b<=5;
    对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30;
    对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50;
    对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50;
    对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。

    资源约定:
    峰值内存消耗 < 256M
    CPU消耗  < 1000ms
    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
    注意: main函数需要返回0
    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
    提交时,注意选择所期望的编译器类型。

    分析

    刚看这题,似乎摸不着头脑,细细欣赏,似乎还可以实现。

    由于数据量可能很大,这里使用了long long类型。

    输入给出了所有数的和s,假设该数列的第一个数为i,那么它的取值范围为[s - n * a, s + n * b]。

    然后对枚举的每个数进行深度优先搜索,就可以得到结果。

    考试时由于在main()函数内重复定义了变量cnt,和全局变量冲突,最后输出的答案一直是0,可惜没时间改了。

    代码实现

    #include <iostream>
    using namespace std;
    long long n, s, a, b;
    long long sum;
    long long cnt = 0;
    long long mo = 100000007;
    int dfs(long long nn, long long rn) {
    	//cout << "dfs  " << nn << ", " << rn << endl;
    	sum += nn;
    	if(rn == 0) {
    		//cout << "sum   " << sum << endl;
    		if(sum == s) {
    			sum -= nn;
    			//cout << "cnt" << endl;;
    			cnt++;
    			cnt %= mo;
    			return 1;
    		} else {
    			sum -= nn;
    			return 0;
    		}
    	}
    	
    	dfs(nn + a, rn - 1);
    	dfs(nn - b, rn - 1);
    	sum -= nn;
    }
    int main(void) {
    	cin >> n >> s >> a >> b;
    	//dfs(2, 3);
    	for(long long i = s - n * a; i < s + n * b; i++)  {
    		sum = 0;
    		dfs(i, n - 1);
    	}
    	cout << cnt << endl;
    	return 0;
    }

    (全文完)

    本文地址:http://www.milkcu.com/blog/archives/2014pa10.html

  • 相关阅读:
    【原】Ubuntu13.04安装、卸载Gnome3.8
    【原】安装、卸载、查看软件时常用的命令
    【原】中文Ubuntu主目录下的文档文件夹改回英文
    【原】Ubuntu ATI/Intel双显卡 驱动安装
    【转】Hadoop vs Spark性能对比
    【译】Spark调优
    【转】Spark源码分析之-scheduler模块
    【转】Spark源码分析之-deploy模块
    【转】Spark源码分析之-Storage模块
    【转】弹性分布式数据集:一种基于内存的集群计算的容错性抽象方法
  • 原文地址:https://www.cnblogs.com/milkcu/p/3808863.html
Copyright © 2011-2022 走看看