如何解决" Zero-One"多编码解决方案?

时间:2015-02-01 22:39:09

标签: algorithm

给定数字N,找到最小的"零 - 一"数字S是N的倍数.A"零 - 一" number由数字0和/或1组成。

E.g。如果N=4S=100 此处1004的最小整数倍,其表示仅包含0和/或1位数。

我尝试以蛮力的方式进行,但我正在寻找一种有效的解决方案。

12 个答案:

答案 0 :(得分:17)

您需要搜索最小的数字,以便将N乘以。

我会从最低有效数字开始逐步构建数字。

假设N = 7。乘数的可能最低有效位数是多少?它将是一个数字,当您乘以7时,将得到最低有效数字为0或1的结果。如果您尝试0-9的数字,它只能是'0'或3'。

+-------+--------+------+
| Digit | Result | Pass |
+-------+--------+------+
| 0     |  0     | Yes  |
| 1     |  7     | No   |
| 2     | 14     | No   |
| 3     | 21     | Yes  |
| 4     | 28     | No   |
| 5     | 35     | No   |
| 6     | 42     | No   |
| 7     | 49     | No   |
| 8     | 56     | No   |
| 9     | 63     | No   |
*-------*--------*------*

然后你尝试第二个最低有效数字。您现在将尝试00,10,20,30,40,50,60,70,80,90和03,13,23,43,53,63,73,83,93。成功的候选人将乘以7,产生一个数字,其中两个最低有效数字为0或1.你留下'43','30','00'和'01'。< / p>

使用第3位数字重复此过程,找到产生符合质量的3个最低有效数字的倍数的数字。

在此过程中,您会找到一个数字,其中所有数字都符合质量,这就是您的答案。在N = 7的情况下,您已经找到了第3位数字。 (7 * 143 == 1001)。

答案 1 :(得分:4)

以下是使用BFS的替代方法。

从值为1的根节点开始,构建是否附加0或1的决策树。因此,每个节点使用数字0和1表示一个数字。然后执行BFS以找到最低的这个数字,这也是输入数字的倍数。

此解决方案还利用modulo(输入数字)来计算非常大的结果。代码中的注释中提供了完整描述。

您还可以在ideone中访问相同的代码段。

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;

public class Main {
    // Return the smallest multiple of the number (as a string) consisting only of digits 0 and 1
    //
    // All possible digits that can be constructed using the digits 0/1 can be represented
    // as a tree, where at each level, appending a 0 is one branch and appending a 1 is another
    //
    // If we perform BFS on this tree, the first number we see which is an exact multiple of the input
    // number will be the result (since it will be the smallest). Make sure to consider left
    // branch (i.e. 0) before considering the right branch (i.e. 1)
    //
    // The 2 paths we take at each level when the current number is num:
    //      (num * 10)
    //      (num * 10) + 1
    // 
    // Since the result can grow huge quite easily, it might not be possible to store the result in a
    // 32 or even a 64 bit int/long variable.
    //
    // One alternative is to use BigNumber, but a simpler alternative exists if we leverage modulo.
    //
    // The operations we perform above (i.e. multiplications and additions) will retain the useful part
    // of the result when using modulo. We use the given number itself as the modulo, and when we see a
    // result of 0, it means we have found a number which is an exact multiple of the input number.
    //
    // To reconstruct the number, we need to store the parent nodes of each node, when adding the node
    // in the queue (similar to using BFS for computing shortest path)
    //
    // We will also need to know if we appended a 0 or a 1 at each step, and so we add this information
    // as part of the node data structure as well.
    //
    // Re-visiting nodes is unecessary since we have seen this modulo result (i.e. value % num) already.
    // Any additional digits we add from now will only make the number longer and we already are tracking
    // the path for this same modulo result we've seen earlier.
    //
    public static String multiple(int num) {
        if (num < 0) {
            throw new IllegalArgumentException("Invalid args");
        }

        String result = "0";

        if (num > 0) {
            // An array to mark all the visited nodes
            boolean[] isVisited = new boolean[num];
            Arrays.fill(isVisited, false);

            // The queue used by BFS
            Queue<Node> queue = new ArrayDeque<>();

            // Add the first number 1 and mark it visited
            queue.add(new Node(true, 1 % num, null));
            isVisited[1 % num] = true;

            // The final destination node which represents the answer
            Node destNode = null;

            while (!queue.isEmpty()) {
                // Get the next node from the queue
                Node currNode = queue.remove();

                if (currNode.val == 0) {
                    // We have reached a valid multiple of num
                    destNode = currNode;
                    break;
                } else {
                    // Visit the next 2 neighbors
                    // Append 0 - (currNode.val * 10)
                    // Append 1 - (currNode.val * 10) + 1

                    // Append a '0'
                    int val1 = (currNode.val * 10) % num;
                    if (!isVisited[val1]) {
                        queue.add(new Node(false, val1, currNode));
                        isVisited[val1] = true;
                    }

                    // Append a '1'
                    int val2 = (val1 + 1) % num;
                    if (!isVisited[val2]) {
                        queue.add(new Node(true, val2, currNode));
                        isVisited[val2] = true;
                    }
                }
            }

            // Trace the path from destination to source
            if (destNode == null) {
                throw new IllegalStateException("Result should not be null");
            } else {
                StringBuilder reverseResultBuilder = new StringBuilder();
                Node currNode = destNode;
                while (currNode != null) {
                    reverseResultBuilder.append(currNode.isDigitOne ? '1' : '0');
                    currNode = currNode.parent;
                }
                result = reverseResultBuilder.reverse().toString();
            }
        }

        return result;
    }

    // Node represents every digit being appended in the decision tree
    private static class Node {
        // True if '1', false otherwise (i.e. '0')
        public final boolean isDigitOne;
        // The number represented in the tree modulo the input number
        public final int val;
        // The parent node in the tree
        public final Node parent;

        public Node(boolean isDigitOne, int val, Node parent) {
            this.isDigitOne = isDigitOne;
            this.val = val;
            this.parent = parent;
        }
    }

    public static void main(String[] args) {
        int num = new Scanner(System.in).nextInt();
        System.out.println("Input number: " + num);
        System.out.println("Smallest multiple using only 0s and 1s as digits: " + Main.multiple(num));
    }
}

答案 2 :(得分:2)

怎么样:你尝试了一系列数字:1,10,100,1000,10000,..... 并将每个数字除以N,然后记录余数  例如。 N = 9,1 / 9 = 1 10 = 1(mod 9),100 = 1(mod 9),....  关键是你需要从这个系列中选择特定的数字,并确保这些余数加起来为N的倍数。  例如。 N = 9,然后你加1,10,100,....

我建议使用该算法:一旦系列的其余部分的总和&gt; N,尝试在余数中搜索总计为N等的余数

答案 3 :(得分:1)

迭代for循环,将输入数转换为二进制数,然后将二进制数转换为long,并检查该数字是否可被输入数整除。

这是代码:

private Long getno(int n) {

        for(int i=1;;i++)
        {
            String binary=Integer.toBinaryString(i);

            Long no=Long.parseLong(binary);

            if(no%n==0)
            {
                return no;
            }
        }


    }

答案 4 :(得分:1)

这就是我在C中解决这个问题的方法,但仍需要很长时间。

#include <stdio.h>
int getZeroOneMultipler(int number) {
  long multiplier = 1;
  while(1) {
    long product = multiplier++ * number;
    long temp = product;
    while ( temp != 0 ) {
      int digit = temp % 10;
      if ( digit != 0 && digit != 1 ) {
        break;
      }
      temp /= 10;
    }
    if ( temp == 0 ) {
      return product;
    }
  }
}

int main(int argc, char** argv) {
  int i = 0;
  for ( i = 0; i < 100; i++) {
      printf("%d = %d\n", i, getZeroOneMultipler(i));
  }
  return 0;
}

答案 5 :(得分:0)

使用Andrew的方法

public class ZeroOne {
private int num;
private ArrayList<String> correctLeastSigDigit = new ArrayList<String>();
private ArrayList<String> toBeRemoved = new ArrayList<String>();

public ZeroOne(int num){
    this.num = num;
}

//get the number to multiply number to get a zero one
public int solve(){
    int digit =1;

    //get the least significant digits that will give is a 0 or 1 ending
    for(int i=0; i < 10; i++){
        String strNum = String.valueOf(this.num * i);
        if(checkLastSigDigits(strNum, 0) == true){
            correctLeastSigDigit.add(String.valueOf(i));
        }
    }//for

    while(true){
        for(int i=0; i < correctLeastSigDigit.size(); i++){
            String temp = correctLeastSigDigit.get(i);
            for(int j=1; j < 10;j++){
                if(checkLastSigDigits(String.valueOf(this.num * Integer.valueOf("" + j + temp)),digit)){
                    if(isZeroOne(String.valueOf(this.num * Integer.valueOf("" + j + temp)))){
                        return this.num * Integer.valueOf("" + j + temp);
                    }
                    correctLeastSigDigit.add("" + j + temp);
                }
                toBeRemoved.remove(temp);
            }
        }
        for(String s: toBeRemoved){
            correctLeastSigDigit.remove(s);
        }
        digit++;
    }
}

public boolean checkLastSigDigits(String num, int n){
    for(int i=num.length() - 1; i >= num.length() - 1 - n; i--)
    if(num.charAt(i) != '1' && num.charAt(i) != '0'){
        return false;
    }
    return true;
}
public boolean isZeroOne(String num){
    for(int i =0; i< num.length();i++){
        if(num.charAt(i) != '1' && num.charAt(i) != '0'){
            return false;
        }
    }
    return true;
}

}

答案 6 :(得分:0)

static void Main(string[] args)
{
  int x = Convert.ToInt32(Console.ReadLine());

  int result = 0;
  for (int i = 1; i < int.MaxValue; i++)
  {
    result = Convert.ToInt32( Convert.ToString(i, 2) );
    if (result % x == 0) break;  
  }

  Console.WriteLine(result);
}

答案 7 :(得分:0)

这是我的解决方案:

最小&#34;零一&#34;数字S可以是{1,10,11,100,101,110,111,1000,...中的任何一个。 。 。这是二进制数。所以,

  1. 贯穿循环
  2. 以二进制形式转换它们
  3. 除以数字N并检查提醒。
  4. 打印出结果。

    课程计划 {

    static void Main(string[] args)
    {
    
        int N;
        String Temp_S;
        int loop;
        int S;
    
        N = Convert.ToInt32(Console.ReadLine());
        for (loop = 1; loop <= 100; loop++)
        {
            Temp_S = Convert.ToString(loop, 2);
            S = Convert.ToInt32(Temp_S);
            if (S % N ==0)
            { 
            Console.WriteLine(S);
            Console.ReadLine();
            break;
        }
        }
    }
    

    } }

答案 8 :(得分:0)

要求:对于任何数字N,找到一个数字S(+ ve整数),它是N的倍数,但是为零。 简要算法: 从列表中的1开始。 然后迭代上面的列表并为该列表的每个可能值计算以下两个值 x = list[i]*10; y = x+1; dummylist.Add(x); dummyList.Add(y); list = dummy;

这是C#代码(a有一些虚拟值)

 long a = 88888;

        List<long> list = new List<long>();
        list.Add(1);
        bool flag = true;

        while (flag)
        {
            List<long> dummy = new List<long>();
            for (int i = 0; i < list.Count; i++)
            {
                var r = list[i] * 10;
                var r1 = r + 1;
                if (r % a == 0)
                {
                    Console.WriteLine(r);
                    flag = false;
                    break;
                }
                dummy.Add(r);
                dummy.Add(r1);
            }
            list = dummy;
        }

答案 9 :(得分:0)

import React, { forwardRef } from "react";
import styled from "styled-components";
import { DatePicker, IDatePicker, IDatePickerProps } from "office-ui-fabric-react";

interface IProps extends IDatePickerProps {
    label?: string;
    error?: string;
}


export const Date = forwardRef<IDatePicker, IProps>(({ ...props }, ref) => {


    return <DateStyled>

        <DatePicker  {...props} componentRef={ref || undefined} />

    </DateStyled>
});

const DateStyled = styled.div``;

答案 10 :(得分:0)

一个很好的例子,用c#进行性能测试。

using System;
using System.IO;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        // //23799731 FINAL SOLUTION
        // 
        // //938213137
        // //1100001010001000001110100100111
        // //1100001010001000001110100100111
        // //1100001010011111111111111110111
        // 
        // //69999993

        struct Node
        {
            public int _mod;
            public byte _len;
        }

        static string GetOutput(Dictionary<Int64, Node> way1, Dictionary<Int64, Node> way2, Int64 linkPos, Int64 N)
        {
            string data = "";

            Int64 prev = linkPos;
            while (prev != 0)
            {
                Int64 temp = way1[prev]._mod;
                if (temp * 10 % N == prev)
                {
                    data = data + "0";
                }
                else if ((temp * 10 + 1) % N == prev)
                {
                    data = data + "1";
                }
                else
                {
                    data = data + "x";
                }
                prev = temp;
            }


            int size = data.Length;
            string strt = "";
            for (int i = 0; i < size; i++)
            {
                strt = strt + data[size - i - 1];
            }

            Int64 next = linkPos;
            while (next != 0)
            {
                Int64 temp = way2[next]._mod;
                if (next * 10 % N == temp)
                {
                    strt = strt + "0";
                }
                else if ((next * 10 + 1) % N == temp)
                {
                    strt = strt + "1";
                }
                else {
                    strt = strt + "x";
                }
                next = temp;
            }
            return strt;
        }

        static string DoubleBFS(Int64 N)
        {
            Dictionary<Int64, Node> way1 = new Dictionary<Int64, Node>();
            Dictionary<Int64, Node> way2 = new Dictionary<Int64, Node>();
            Queue<Node> que1 = new Queue<Node>();
            Queue<Node> que2 = new Queue<Node>();

            Node node;
            node._mod = 0;
            node._len = 0;
            way1[1] = node;

            node._mod = 1;
            node._len = 1;
            que1.Enqueue(node);

            for (Int64 i = 0; i < 10; i++)
            {
                Int64 mul = i * N;
                Int64 mod = mul % 10;
                if (mod == 0 || mod == 1)
                {
                    Int64 ddd = mul / 10;
                    node._mod = 0;
                    node._len = 0;
                    way2[ddd] = node;

                    node._mod = (int)ddd;
                    node._len = 1;
                    que2.Enqueue(node);
                }
            }

            Int64 linkPos = N;
            Int64 linkLen = N;
            string data = "";
            while (que1.Count > 0 && que2.Count > 0 && data.Length == 0)
            {
                if (way1.Count <= way2.Count)
                {
                    Node head = que1.Peek();
                    int levl = head._len;
                    while (que1.Count > 0)
                    {
                        head = que1.Peek();
                        if (head._len != levl) break;

                        Int64 temp = head._mod;
                        Int64 xxxx = (temp * 10) % N;
                        if (!way1.ContainsKey(xxxx))
                        {
                            way1[xxxx] = head;
                            node._mod = (int)xxxx;
                            node._len = (byte)(head._len + 1);
                            que1.Enqueue(node);
                        }

                        if (way2.ContainsKey(xxxx))
                        {
                            int linkLenNew = way2[xxxx]._len + way1[xxxx]._len;
                            if (linkLenNew < linkLen)
                            {
                                linkPos = xxxx;
                                linkLen = linkLenNew;
                            }
                        }

                        xxxx = (temp * 10 + 1) % N;
                        if (!way1.ContainsKey(xxxx))
                        {
                            way1[xxxx] = head;
                            node._mod = (int)xxxx;
                            node._len = (byte)(head._len + 1);
                            que1.Enqueue(node);
                        }

                        if (way2.ContainsKey(xxxx))
                        {
                            int linkLenNew = way2[xxxx]._len + way1[xxxx]._len;
                            if (linkLenNew < linkLen)
                            {
                                linkPos = xxxx;
                                linkLen = linkLenNew;
                            }
                        }
                        que1.Dequeue();
                    }

                    if (linkPos != N)
                    {
                        data = GetOutput(way1, way2, linkPos, N);
                    }
                }
                else
                {
                    Node head = que2.Peek();
                    int levl = head._len;
                    while (que2.Count > 0)
                    {
                        head = que2.Peek();
                        if (head._len != levl) break;
                        for (Int64 i = 0; i < 10; i++)
                        {
                            Int64 mul = i * N + head._mod;
                            Int64 mod = mul % 10;
                            if (mod == 0 || mod == 1)
                            {
                                Int64 ddd = mul / 10;
                                if (!way2.ContainsKey(ddd))
                                {
                                    way2[ddd] = head;
                                    node._mod = (int)ddd;
                                    node._len = (byte)(head._len + 1);
                                    que2.Enqueue(node);
                                }
                                if (way1.ContainsKey(ddd))
                                {
                                    int linkLenNew = way2[ddd]._len + way1[ddd]._len;
                                    if (linkLenNew <= linkLen)
                                    {
                                        linkPos = ddd;
                                        linkLen = linkLenNew;

                                        string answ = GetOutput(way1, way2, linkPos, N);
                                        if (data.Length == 0 || data.CompareTo(answ) > 0)
                                        {
                                            data = answ;
                                        }
                                    }
                                }
                            }
                        }
                        que2.Dequeue();
                    }
                }
            }
            return data;
        }

        static void Main(string[] args)
        {
            StreamReader sr = new StreamReader(Console.OpenStandardInput());
            StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());
            Int64 T = Convert.ToInt64(sr.ReadLine());
            sw.WriteLine(DoubleBFS(T));
            sw.Flush();
        }
    }
}

答案 11 :(得分:-1)

这是我的算法:

1)从10开始(二进制2)。 2)将其转换为字符串,因此它将是&#34; 10&#34; 3)将此字符串转换为十进制 4)将该小数除以输入n。 5)在二进制数10中加1,结果为11 6)重复2-5直到余数为0;