【九度】题目1358:陈博的平均主义

108 篇文章 0 订阅
102 篇文章 5 订阅
题目1358:陈博的平均主义
时间限制
:1 秒内存限制:32 兆特殊判题:否提交:294解决:155
题目描述:
在JOBDU团队里,陈博是最讲平均主义的人了,但并不是像梁山好汉那样能够做到有钱同花,有肉同吃,毕竟,他还是被家里的领导管着的……陈博的平均主义,就只能体现在他对数字的喜好了。陈博特别喜欢一类“平均数”,“平均数”的具体定义为:
对于一个数字,当其以十进制形式表示时,我们可以将其每一位的数字分为两堆,两堆数字的和是相等的。
例如,数字363就是一个理想的平均数,因为我们可以将其分为相等的两堆{3, 3}, {6}。
现在陈博就要考考你了,看你是否掌握了他的平均主义。假如给你一个整数范围[A, B],你是否能找出,在这个范围内,究竟有多少“平均数“?
输入:
每个测试文件包含多个测试案例,每个测试案例一行,每行包括两个整数A、B,其中[A,B]这个待查看的整数范围。其中我们能保证1 <= A <= B <= 109,且0 <= B – A <= 105。
输出:
对于每个整数范围[A, B],返回一个整数,表明这个整数范围内有多少个整数是陈博所喜欢的“平均数”。
样例输入:
1 50
1 1000
样例输出:
4
135
答疑:
解题遇到问题?分享解题心得?讨论本题请访问:http://t.jobdu.com/thread-8081-1-1.html
【解题思路】
其实和Jobdu MM分水果是一样的。基本思路。
1、因为个位数是不可能为平均数的。那么第一步就计算a,A=Math.max(11, a);这样缩小了范围,当然对于效率影响不会很大。
2、foreach(A,B),计算每个数的所有位数之和。如果为奇数,必然不会是平均数,如果是偶数,再DP,就是结果。

Java AC

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class Main {
	/*
	 * 1358
	 */
	public static void main(String[] args) throws Exception {
		StreamTokenizer st = new StreamTokenizer(new BufferedReader(
				new InputStreamReader(System.in)));
		while (st.nextToken() != StreamTokenizer.TT_EOF) {
			int a = (int) st.nval;
			st.nextToken();
			int b = (int) st.nval;
			a = Math.max(11, a);
			int count = 0;
			for (int i = a; i <= b; i++) {
				String astr = i + "";
				char array[] = astr.toCharArray();
				int size = array.length;
				int tempSum = 0;
				for (int j = 0; j < size; j++) {
					tempSum += array[j] - '0';
				}
				if (tempSum % 2 != 0) {
					continue;
				} else {
					int midSum = tempSum / 2;
					int dp[] = new int[midSum + 1];
					for (int j = 0; j < size; j++) {
						int num = array[j] - '0';
						for (int k = midSum; k >= num; k--) {
							dp[k] = Math.max(dp[k], dp[k - num] + num);
						}
					}
					if (dp[midSum] == midSum) {
						count++;
					}
				}
			}
			System.out.println(count);
		}
	}
}
/**************************************************************
Problem: 1358
User: wzqwsrf
Language: Java
Result: Accepted
Time:860 ms
Memory:87240 kb
****************************************************************/
C++ AC

#include <stdio.h>
#include <string.h>
const int maxn = 102;
const int maxLen = 10;
int numArr[maxLen];
int dp[maxn];
int a, b;
int i, j;
int count;
 
int max(int x, int y){
    return x > y ? x : y;
}
bool isTrue(int num){
    int tempSum = 0;
    int len = 0;
    int k = 0;
    while(num){
        numArr[k] = num % 10;
        tempSum += numArr[k];
        num /= 10;
        k++;
    }
    len = k;
    if(tempSum % 2 != 0){
        return false;
    }
    int midSum = tempSum / 2;
    for (j = 0; j < len; j++) {
        for (k = midSum; k >= numArr[j]; k--) {
            dp[k] = max(dp[k], dp[k - numArr[j]] + numArr[j]);
        }
    }
    if (dp[midSum] == midSum) {
        return true;
    }
    return false;
}
int main(){
    while(scanf("%d %d", &a, &b) != EOF){
        count = 0;
        a = max(11, a);
        for(i = a; i <= b; i++){
            memset(dp, 0, sizeof(dp));
            if(isTrue(i)){
                count++;
            }
        }
        printf("%d\n", count);
    }
    return 0;
}
/**************************************************************
    Problem: 1358
    User: wangzhenqing
    Language: C++
    Result: Accepted
    Time:160 ms
    Memory:1020 kb
****************************************************************/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值