首页 > 试题广场 >

神奇数

[编程题]神奇数
  • 热度指数:3233 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
东东在一本古籍上看到有一种神奇数,如果能够将一个数的数字分成两组,其中一组数字的和等于另一组数字的和,我们就将这个数称为神奇数。例如 242 就是一个神奇数,我们能够将这个数的数字分成两组,分别是 {2,2} 以及 {4} ,而且这两组数的和都是 4 .东东现在需要统计给定区间中有多少个神奇数,即给定区间 [l, r] ,统计这个区间中有多少个神奇数,请你来帮助他。

数据范围:

输入描述:
输入包括一行,一行中两个整数l和r(1 ≤ l, r ≤ 10^9, 0 ≤ r - l ≤ 10^6),以空格分割


输出描述:
输出一个整数,即区间内的神奇数个数
示例1

输入

1 50

输出

4
示例2

输入

11 11

输出

1
import java.util.Arrays;
import java.util.Scanner;

/**
 * 京东2018秋招Android
 * 神奇数
 * 东东在一本古籍上看到有一种神奇数,如果能够将一个数的数字分成两组,其中一组数字的和等于另一组数字的和,
 * 我们就将这个数称为神奇数。例如242就是一个神奇数,我们能够将这个数的数字分成两组,分别是{2,2}以及{4},
 * 而且这两组数的和都是4.东东现在需要统计给定区间中有多少个神奇数,即给定区间[l, r],统计这个区间中有多
 * 少个神奇数,请你来帮助他。
 * 输入描述:
 * 输入包括一行,一行中两个整数l和r(1 ≤ l, r ≤ 10^9, 0 ≤ r - l ≤ 10^6),以空格分割
 * <p>
 * <p>
 * 输出描述:
 * 输出一个整数,即区间内的神奇数个数
 * <p>
 * 输入例子1:
 * 1 50
 * <p>
 * 输出例子1:
 * 4
 */
public class MagicNumber {
    /**
     * 首先判断数组能否被平分,即数组分割问题,
     * dp[i][j]
     * 表示数组前 i
     * 个数字能否求和得到 j
     * 则
     * dp[i][j]=dp[i−1][j]||dp[i−1][j−array[i]]
     * 其中||是逻辑或运算。
     * 优化:
     * 1、若sum(array)为奇数,直接返回false
     * 2、使用逆序循环将dp数组简化为一维数组
     */

    public static boolean isMagic(int[] nums, int sum) {
        int len = nums.length;

        if (sum % 2 != 0)
            return false;

        int mid = sum / 2;

        int[] dp = new int[mid + 1];
        dp[0] = 1;
        for (int i = 0; i < len; i++) {
            for (int j = mid; j > 0; j--) {
                if (j >= nums[i] && nums[i] != -1)
                    dp[j] = Math.max(dp[j], dp[j - nums[i]]);
            }
        }
        if (dp[mid] > 0)
            return true;
        else
            return false;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int l = sc.nextInt();
        int r = sc.nextInt();

        int result = 0;

        for (int i = l; i <= r; i++) {

            int num = i;
            int[] nums = new int[10];
            int sum = 0;
            Arrays.fill(nums, -1);
            int index = 0;
            while (num > 0) {
                int temp = num % 10;
                nums[index++] = temp;
                sum += temp;
                num = num / 10;
            }

            if (isMagic(nums, sum)) {
                result++;
            }
        }

        System.out.println(result);
    }

}
发表于 2018-05-20 18:02:03 回复(0)
更多回答
#include <iostream>
#include <vector> #include <algorithm> using namespace std; bool judge(vector<int>& nums,int sum){     if(sum%2!=0) //如果累加和为奇数,直接false         return false;     int n=nums.size();     int target=sum/2; //目标累加和     vector<bool> dp(target+1,false); //dp[i][j]为前i个数的累加和能否为j,简化为一维数组     dp[0]=true;     for(int i=1;i<=n;++i)         for(int j=target;j>=nums[i];--j) //0-1背包问题,逆序循环             dp[j]=dp[j-nums[i]] || dp[j];     return dp[target]; } vector<int> get_num(int i){ //取出每一位数字     vector<int> res;     while(i){         res.push_back(i%10);         i/=10;     }     return res; } int main(){     int l,r;     cin>>l>>r;     int cnt=0;     for(int i=l;i<=r;++i){         vector<int> nums=get_num(i);         int sum=accumulate(nums.begin(),nums.end(),0);         if(judge(nums,sum))             cnt++;     }     cout<<cnt;     return 0; }

编辑于 2019-02-22 14:23:18 回复(5)
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
 
bool IsNum(int &in){
       vector<int> arry;
       int num=in;
       int half=0;
       while(num){//将数字打散存入arry数组
              arry.push_back(num%10);
              half+=num%10;
              num/=10;
       }
       if (half%2!=0) return false;
       half/=2;
       vector<int> dp(half+1); //之后这一小段用的是01背包,判断能装下最大的数和一半是否相等。
       for (int i=0;i<arry.size();i++){
              for(int j=half;j>=arry[i];j--){
                     dp[j]=max(dp[j],dp[j-arry[i]]+arry[i]);
              }
       }
       return dp[half]==half;
}
 
 
 
int main()
{
       int l,r;
       cin>>l>>r;
       int count=0;
       for(int i=l;i<=r;i++){
              if(IsNum(i))
                     count++;//如果是神奇数,计数+1
       }
       cout<<count<<endl;
       return 0;
}

编辑于 2018-10-04 14:59:47 回复(1)
先整了个递归,然后按照递归搞了个记忆化搜索,按道理来说应该和动规的速度差不多,然而并没有更快,所以懒得改动规了。大题思路就是将区间中的每个数打散成一个只有个位数的数组,然后判断这个数组是否能划分为等和的两部分。如果数组的总和sum不能被2整除就肯定不能完成这一壮举,否则采取从左往右试的尝试模型去凑sum/2,每次可以有选当前数与不选当前数两种选择,如果中途凑齐了sum/2或者到了最后一个数凑齐了sum/2就肯定可以完成划分。
暴力递归版本
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] params = br.readLine().split(" ");
        int left = Integer.parseInt(params[0]);
        int right = Integer.parseInt(params[1]);
        int count = 0;
        for(int num = left; num <= right; num++){
            char[] digits = String.valueOf(num).toCharArray();
            int[] arr = new int[digits.length];
            int sum = 0;
            for(int i = 0; i < arr.length; i++) {
                arr[i] = digits[i] - '0';
                sum += arr[i];
            }
            if(isValid(arr, sum)) count++;
        }
        System.out.println(count);
    }
    
    private static boolean isValid(int[] nums, int sum) {
        if(sum % 2 != 0) return false;
        int target = sum >> 1;
        int n = nums.length;
        return recurrent(nums, 0, target) > 0;
    }
    
    private static int recurrent(int[] nums, int depth, int rest) {
        if(depth == nums.length) return rest == 0? 1: 0;
        if(rest == 0) return 1;
        if(rest < 0) return 0;
        return recurrent(nums, depth + 1, rest - nums[depth]) + recurrent(nums, depth + 1, rest);
    }
}
记忆化搜索版本
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] params = br.readLine().split(" ");
        int left = Integer.parseInt(params[0]);
        int right = Integer.parseInt(params[1]);
        int count = 0;
        for(int num = left; num <= right; num++){
            char[] digits = String.valueOf(num).toCharArray();
            int[] arr = new int[digits.length];
            int sum = 0;
            for(int i = 0; i < arr.length; i++) {
                arr[i] = digits[i] - '0';
                sum += arr[i];
            }
            if(isValid(arr, sum)) count++;
        }
        System.out.println(count);
    }
    
    private static boolean isValid(int[] nums, int sum) {
        if(sum % 2 != 0) return false;
        int target = sum >> 1;
        int n = nums.length;
        int[][] memory = new int[n + 1][target + 1];
        return recurrent(nums, 0, target, memory) > 0;
    }
    
    private static int recurrent(int[] nums, int depth, int rest, int[][] memory) {
        if(depth == nums.length) return rest == 0? 1: 0;
        if(rest == 0) return 1;
        if(rest < 0) return 0;
        if(memory[depth][rest] > 0) return memory[depth][rest];
        memory[depth][rest] = recurrent(nums, depth + 1, rest - nums[depth], memory) + recurrent(nums, depth + 1, rest, memory);
        return memory[depth][rest];
    }
}

发表于 2021-11-30 18:11:53 回复(0)
#include <bits/stdc++.h>
using namespace std;

bool F(int x){
    int k=0, s=0, t, a[11];
    while(x){
        t = x%10;
        if(t){
            a[k++] = t;
            s += t;
        }
        x /= 10;
    }
    if(s&1)
        return 0;
    s >>= 1;
    int dp[s+1];
    memset(dp, 0, sizeof(dp));
    dp[0] = 1;
    for(int i=0;i<k;i++)
        for(int j=s;j>=a[i];j--)
            dp[j] = dp[j] || dp[j-a[i]];
    return dp[s];
}

int main(){
    int l, r, cnt=0;
    scanf("%d%d", &l, &r);
    for(int i=l;i<=r;i++)
        if(F(i))
            cnt++;
    printf("%d\n", cnt);
    return 0;
}

发表于 2020-10-09 00:27:46 回复(0)
思路:设数X,先求出X的每位数存到vector中,再求出X每位数之和sum,
若为奇数则舍弃,
若为偶数则判断是否是神奇数,若是神奇数,则vector中必存在若干个数的和为sum/2,
所以只需判断sum/2 减去vector中的数是否为0即可
ps:感觉思路没啥问题,但只通过40%,很悲伤
      
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;


int main()
{
    int l,r;
    cin>>l>>r;
    int total = 0;
    for(int i = l; i <= r; i++)
    {
        int n=i;
        int sum = 0;
        int half = 0;
        vector<int> vec;
        while(n > 0)
        {
            vec.push_back(n % 10);
            sum += n % 10;
            n = n / 10;
        }
        if(sum % 2 == 0)
        {
            half = sum / 2;
            sort(vec.begin(),vec.end());
            for(int j=vec.size()-1;j>=0;j--)
            {
                if(half>=vec[j])
                {
                    half=half-vec[j];
                    if(half==0)
                    {
                        total++;
                        break;
                    }
                }
            }
        }
    }
    cout << total;
    return 0;
}

//经好心人指出,已改正
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    int l,r;
    cin>>l>>r;
    int total = 0;
    for(int i = l; i <= r; i++)
    {
        int n=i;
        int sum = 0;
        int half = 0;
        vector<int> vec;
        while(n > 0)
        {
            vec.push_back(n % 10);
            sum += n % 10;
            n = n / 10;
        }
        if(sum % 2 == 0)
        {
            half = sum / 2;
            vector<int> re(half+1); 
            for(int i=0;i<vec.size();i++)
            {
                for(int j=half;j>=vec[i];j--)
                {
                    re[j]=max(re[j],re[j-vec[i]]+vec[i]);
                }
            }
            if(half==re[half])
            {
              total++; 
            }
         }
    }
    cout << total;
    return 0;
}

编辑于 2019-06-11 20:06:21 回复(4)
import java.util.*;

public class Main {
    private static Map<Integer, Boolean> map = new HashMap<>();
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int l = sc.nextInt(), r = sc.nextInt();
        int ans = 0;
        for (int i=l; i<=r; i++) {
            if (isMiraculous(i)) { ans++; }
        }
        System.out.println(ans);
    }
    private static boolean isMiraculous(int p) {
        String sp = String.valueOf(p);
        int n = sp.length();
        char[] sa = sp.toCharArray();
        Arrays.sort(sa);
        Integer sorted = Integer.valueOf(new String(sa));
        if (map.containsKey(sorted)) {
            return map.get(sorted);
        }
        int in = sp.chars().map(c -> c -'0').sum();
        if (in % 2 != 0) {
            map.put(sorted, false);
            return false;
        }
        int[] ia = sp.chars().map(c -> c -'0').toArray();
        for (int i=1; i<=(1<<n); i++) {
            int tmp = i; int left = 0 ,right = 0;
            for (int j=0; j<n; j++) {
                if (((tmp >> j) & 1)== 0) {
                    left+=ia[j];
                }
                else {
                    right+=ia[j];
                }
            }
            if (left == right) {
                map.put(sorted, true);
                return true;
            }
        }
        map.put(sorted, false);
        return false;
    }
}
发表于 2019-03-02 19:44:28 回复(0)

import java.util.Scanner;

public class Main {

public static void main(String[] args) {
    Main test = new Main();
    Scanner in = new Scanner(System.in);
    int l, n;
    l = in.nextInt();
    n = in.nextInt();
    in.close();

    int sum = 0;

    for(int i = l; i <= n; i++){
        if(test.checkNumber(i))
            sum++;
    }

    System.out.println(sum);

}

private boolean checkNumber(int N){
    int B_sum = 0,n = N,cur = 0;
    int[] str = new int[10];
    while(n > 0){
        str[cur] = n % 10;
        B_sum += str[cur];
        cur++;
        n /= 10;
    }

    if((B_sum % 2) != 0) return false;

    B_sum /= 2;

    boolean[] f = new boolean[41];

    f[str[0]] = true;

    for(int i = 1; i < cur; i++){
        int value = str[i];
        for(int j = 40; j >= 0; --j){         //只能逆序循环,因为下一行会把f[j+value]改为true
            if(f[j] && j + value <= 40)       //顺序循环的话,j=k时,将k+value设为true,当j读到k+value时就出问题了
                f[j + value] = true;
        }

        if(f[B_sum]) {
            return true;
        }
    }

    return false;

}

}

发表于 2018-08-17 14:59:59 回复(0)
import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader df=new BufferedReader(new InputStreamReader(System.in));
        String sd;
        while((sd=df.readLine())!=null){
            String[] ds=sd.split(" ");
            int end=Integer.valueOf(ds[1]);
            if(end<=10){
                System.out.println(0);
                return;
            }
            int num=0;
            int start1=Integer.valueOf(ds[0]);
            int start =start1<=10?10:start1;
            for(int i=start;i<=end;i++){
               if(gg(i)) {
                   num++;
               }
            }
            System.out.println(num);
        }
    }
    public static boolean gg(int h){
        List<Integer> res=new ArrayList<Integer>();
        int  sum=0;
        while(h!=0){
            int h1=h%10;
            sum+=h1;
            res.add(h1);
            h=h/10;
        }
        if(sum%2==1){
            return false;
        }
        sum=sum/2;
        boolean[] res1=new boolean[sum+1];
        res1[0]=true;
        for(Integer d:res){
            for(int i=sum;i>=0;i--){
                if(i>=d){
                    res1[i]=res1[i-d]|res1[i];
                    
                }
            }
        }
        return res1[sum];
    }
}

发表于 2020-08-19 19:33:35 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        // 01背包
        Scanner scan = new Scanner(System.in);
        int l = scan.nextInt();
        int r = scan.nextInt();
        int ans = 0;
        for(int i=l;i<=r;++i){
            if(check(i))
            {
                ++ans;
                //System.out.println(i);
            }
                
        }
        System.out.println(ans);
    }
    private static boolean check(int x){
        ArrayList<Integer>list = new ArrayList<>();
        int v = 0;
        while(x!=0){
            list.add(x%10);
            v+=x%10;
            x/=10;
        }
        if((v&1)==1) return false;
        v/=2;
        int[] dp = new int[v+1];
        dp[0] = 1;
        for(int i=0;i<list.size();++i){
            int t = list.get(i);
            for(int j=v;j>=t;j--){
                if(dp[j-t]!=0) dp[j]=1;
            }
        }
        return dp[v]==1;
    }
}

发表于 2020-07-04 20:38:29 回复(0)
#include <bits/stdc++.h>
using namespace std;
//判断某数是否为神奇数的函数check()
bool check(int n){
    char s[11];//用来存放各位上的数字,0-10对应:个位,十位,百位,千位,万位……
    int cur=0,t=0;//while循环结束后cur表示n是几位数,t表示各位数字之和
    while(n>0){
        s[cur]=n%10;
        t+=s[cur++];
        n/=10;
    }
    if(t%2)return false;//因为 左式=右式=t/2,如果t不能整除2,n必定不是神奇数
    t/=2;
    bool ok[42]={0};//各位数字和最大的值为999999999,和为81,81/2<41;
    ok[s[0]]=true;//固定个位数为左式其中一个数
    for(int i=1;i<cur;i++){//循环剩余的各位数字
        int v=s[i];
        for(int j=41;j>=0;j--){
            if(ok[j]&&j+v<41)
                ok[j+v]=true;//将各位数字相加可能得到的结果,在ok的对应位置置1
        }
        if(ok[t])//当t位置置1时,代表存在使得 左式=右式=t/2 成立的情况
            return true;
    }
    return false;
}
int l,r;
int main(){
    int res=0;
    cin>>l>>r;
    for(int i=l;i<=r;i++)
        if(check(i))
            res++;
    cout<<res<<endl;
    return 0;
}
发表于 2019-08-20 10:51:18 回复(1)

//方法1每个数暴力搜索
//方法2记忆化搜索
//方法3动态规划
//可能是状态不多或是每个数初始化dp数组费时,测下来发现暴力搜索是最快的

#include <bits/stdc++.h>
using namespace std;
#define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

int a[15];
//dp用
int dp[50];

//记忆化搜索用
bool DP[15][50];
bool vis[15][50];

//暴力搜索
bool dfs(int i,int n,int w){
    if(i==n) return w==0;
    if(w<a[i]) return dfs(i+1,n,w);
    return dfs(i+1,n,w-a[i])||dfs(i+1,n,w);
}

//方法1,暴力搜索
bool dynamicP1(int n, int w){
    return dfs(0,n,w);
}

//记忆化搜索
bool ms(int i,int n,int w){
    if(vis[i][w]) return DP[i][w];
    vis[i][w] = 1;
    if(i==n) return DP[i][w] = (w==0);
    if(w<a[i]) return DP[i][w] = dfs(i+1,n,w);
    return DP[i][w] = (dfs(i+1,n,w-a[i])||dfs(i+1,n,w));
}

//方法2:记忆化
bool dynamicP2(int n, int w){
    memset(DP,0,sizeof(DP));
    memset(vis,0,sizeof(vis));
    return ms(0,n,w);
}

//方法3,直接dp
bool dynamicP3(int n, int w){
    memset(dp,0,sizeof(dp));
    dp[0] = 1;
    for(int i=0;i<n;i++){
        for(int j=w;j>=a[i];j--) dp[j] = dp[j]||dp[j-a[i]];
    }
    return dp[w];
}

bool judge(int number){
    int cnt = 0, sum = 0;
    while(number){
        int tmp = number%10;
        if(tmp) {
            a[cnt++] = tmp;
            sum+=tmp;
        }
        number/=10;
    }
    if(sum&1) return 0;
    return dynamicP3(cnt,sum>>1);
}

void solve(int l,int r){
    int ans = 0;
    for(int i=l;i<=r;i++){
        if(judge(i)) ans++;
    }
    cout<<ans<<endl;
}

int main() {
    INIT()
    int l,r;
    while(cin>>l>>r){
        solve(l,r);
    }
    return 0;
}
发表于 2019-06-11 16:44:34 回复(3)
import java.util.Scanner;

public class Main{    public static boolean isJJ(int num) {    int[] arr = new int[11];    int index = 0;    int sum = 0;    for( ; num > 0; index++) {    arr[index] = num % 10;    sum += arr[index];    num /= 10;    }    if(sum % 2 != 0) return false;    return isKK(arr, sum / 2, index);    }    public static boolean isKK(int[] arr, int sum, int index) {  if(sum == 0) return true;    if(index < 0 || sum < 0) return false;    return isKK(arr, sum - arr[index], index - 1) || 
                    isKK(arr, sum, index - 1);    }    public static void main(String[] args) {    Scanner in = new Scanner(System.in);    int l = in.nextInt();    int r = in.nextInt();    int count = 0;    for(int i = l; i <= r; i++) {    if(isJJ(i))  count++;    }    System.out.println(count);    }
}






编辑于 2019-04-13 12:18:54 回复(0)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int num[10],index0;
//bool visit[10];
void reverse_order(int index0){
    for(int i=0,j=index0-1;i<j;i++,j--)
        swap(num[i],num[j]);
}
int separ(int n){
    int sum=0,tmp;
    while(n){
        tmp=n%10;
        num[index0++]=tmp;
        sum+=tmp;
        n/=10;
    }
    return sum;
}

bool is_even(int sum){
    if(sum&1) return false;
    else return true;
}

int DFS(int res,int sum,int j){
    if(sum==res)
        return 1;
    else if(sum<res){
        for(int i=j;i<index0;i++){
            //if(!visit[i]){
                sum+=num[i];
                //visit[i]=true;
                if(DFS(res,sum,i+1)){
                    return 1;
                }
                //visit[i]=false;
                sum-=num[i];
            //}
        }
    }
    return 0;
}

int main(){
    int l,r,sum,len,res,cnt=0;
    scanf("%d%d",&l,&r);
    for(int i=l;i<=r;i++){
        index0=0;
        res=separ(i);
        reverse_order(index0);
        if(is_even(res)){
            res=res>>1;
            //memset(visit,false,sizeof(visit));
            sum=0;
            if(index0>=2&&DFS(res,sum,0))
                cnt++;
        }
    }
    printf("%d",cnt);
    return 0;
}

发表于 2019-04-08 13:09:59 回复(0)
#超时了
def divide(n):
    global digit
    while(n>0):
        digit.append(n % 10)
        n = n // 10
        
def isEqual(index, halfSum):
    global digit
    if(halfSum == 0):
        return True
    if((halfSum!=0 and index == len(digit)) or halfSum < 0):
        return False
    equal = (isEqual(index+1, halfSum - digit[index]) or isEqual(index+1, halfSum))
    return equal
    
global digit
ans = 0
l, r = map(int, input().split())
for num in range(l, r+1):
    digit = []
    divide(num)
    if(sum(digit) % 2 != 0 or len(digit) < 2):
        continue
    else:
        if(isEqual(0, sum(digit)//2)):
            ans += 1
print (ans)

发表于 2019-03-28 09:28:07 回复(0)


import java.util.Arrays;
import java.util.Scanner;

public class Main {
    // 从后往前推,动态规划
    static boolean dp2(int[] arr, int aim) {
        boolean[][] dp = new boolean[arr.length + 1][aim + 1];
        dp[dp.length - 1][0] = true;
        for (int j = 1; j < dp[0].length; j++)
            dp[dp.length - 1][j] = false;
        for (int i = dp.length - 2; i >= 0; i--) {
            dp[i][0] = true;
            for (int j = 1; j < dp[0].length; j++) {
                dp[i][j] = dp[i + 1][j];
                if (j - arr[i] >= 0)
                    dp[i][j] = dp[i][j] || dp[i + 1][j - arr[i]];
                if (dp[i][dp[0].length - 1])
                    return true;
            }
        }
        return dp[0][dp[0].length - 1];
    }

    static boolean func(int num) {
        String temp = String.valueOf(num);
        int[] arr = new int[temp.length()];
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            arr[i] = temp.charAt(i) - '0';
            sum += arr[i];
        }
        if (sum % 2 == 0)
            return dp2(arr, sum / 2);
        else
            return false;
    }

    public static void main(String[] args) {

        Scanner sr = new Scanner(System.in);
        int l = sr.nextInt();
        int r=sr.nextInt();
//        int l = 1, r = 50;
        int count = 0;
        for (int i = l; i <= r; i++) {
            if (func(i)) {
                count++;
                // System.out.print(i+" ");
            }

        }
        System.out.println(count);
    }

}

发表于 2018-08-17 18:13:23 回复(0)
#include <iostream>
#include <algorithm> 
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int func(int *a,int n,int v,int num,int sum){ 
    //if(num*2==sum)    return 1;
    int ans=0;
    for(int i=v;i<n;i++){
        if((num+a[i])*2<=sum){
            if((num+a[i])*2==sum)    return 1;
            else ans+=func(a,n,i+1,num+a[i],sum);    
        }
    }
    return ans;
}
int main(int argc, char** argv) {
    int ans=0,l,r;
    cin>>l>>r;
    for(int i=l;i<=r;i++){
            
        int sum=0,now=i,a[10],count=0;
        while(now!=0){
            sum+=now%10;
            a[count++]=now%10;
            now/=10;
        }
    //    sort(a,a+count);
        if(sum%2==1)    continue;
        if(func(a,count,0,0,sum))    ans++;
    }
    cout<<ans<<endl;
    
    return 0;
}
发表于 2018-08-10 02:28:23 回复(0)
#include<iostream>
#include<vector>
using namespace std;
void divide(vector<int>& vec, int& sum, int n);
bool judge(int n);
bool is_equal(vector<int>& vec, int half);

int main()
{
    int l, r;
    int tot = 0;
    cin >> l >> r;
    for(int i = l; i <= r; i++)
    {
        if(judge(i))//把判断的工作交给judge函数
            tot++;
    }
    cout << tot;
    return 0;
}

void divide(vector<int>& vec, int& sum, int n)//把传入的整数按位切割,并存入一个vector
{
    while(n > 0)
    {
        vec.push_back(n % 10);
        sum += n % 10;
        n = n / 10;
    }
}
bool is_equal(vector<int>& vec, vector<int>::iterator it, int half)//判断能否通过相加得到和的一半
{
    bool equal = false;
    if(half == 0)
    {
        equal = true;
        return equal;
    }
    if((it == vec.end() - 1 && half != 0) || half < 0)
        return equal;
    ++it;
    equal = is_equal(vec, it, half - *it) || is_equal(vec, it, half);//递归求解,加这个数或者不加
    return equal;
}

bool judge(int n)
{
    int sum = 0;
    int half = 0;
    vector<int> vec;
    divide(vec, sum, n);
    if(sum % 2 == 1)
        return false;
    else
    {
        half = sum / 2;
        auto it = vec.begin();
        if(is_equal(vec, it, half))
            return true;
    }
    return false;
}
发表于 2018-06-13 21:06:29 回复(1)