给定数字N,找到最小的"零 - 一"数字S是N的倍数.A"零 - 一" number由数字0和/或1组成。
E.g。如果N=4
则S=100
此处100
是4
的最小整数倍,其表示仅包含0
和/或1
位数。
我尝试以蛮力的方式进行,但我正在寻找一种有效的解决方案。
答案 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,...中的任何一个。 。 。这是二进制数。所以,
打印出结果。
课程计划 {
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;