Quindi ho un numero intero, ad es. 1234567890 e un determinato insieme di numeri, ad es. {4, 7, 18, 32, 57, 68}Come posso determinare se un determinato numero può essere composto da un insieme di numeri?
La domanda è se 1234567890 può essere composto dai numeri indicati (è possibile utilizzare un numero più di una volta e non è necessario utilizzare tutto loro). Nel caso di cui sopra, una soluzione è:
38580246 * + 1 *
(non ha bisogno di dare soluzione specifica, solo se si può fare)
La mia idea sarebbe per provare tutte le soluzioni. Ad esempio, proverei
1 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 4
2 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 8
3 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 12
.....
308 641 972 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 1234567888
308 641 973 * 4 * + 0 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 1234567892 ==> eccede
0 * 4 * + 1 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 7
1 * 4 * + 1 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 11
2 * 4 * + 1 * 7 + 0 * 18 + 0 * 32 + 0 * 57 + 0 * 68 = 15
e così via ...
Ecco il mio codice in C#:
static int toCreate = 1234567890;
static int[] numbers = new int[6] { 4, 7, 18, 32, 57, 68};
static int[] multiplier;
static bool createable = false;
static void Main(string[] args)
{
multiplier = new int[numbers.Length];
for (int i = 0; i < multiplier.Length; i++)
multiplier[i] = 0;
if (Solve())
{
Console.WriteLine(1);
}
else
{
Console.WriteLine(0);
}
}
static bool Solve()
{
int lastIndex = 0;
while (true)
{
int comp = compare(multiplier);
if (comp == 0)
{
return true;
}
else if (comp < 0)
{
lastIndex = 0;
multiplier[multiplier.Length - 1]++;
}
else
{
lastIndex++;
for (int i = 0; i < lastIndex; i++)
{
multiplier[multiplier.Length - 1 - i] = 0;
}
if (lastIndex >= multiplier.Length)
{
return false;
}
multiplier[multiplier.Length - 1 - lastIndex]++;
}
}
}
static int compare(int[] multi)
{
int osszeg = 0;
for (int i = 0; i < multi.Length; i++)
{
osszeg += multi[i] * numbers[i];
}
if (osszeg == toCreate)
{
return 0;
}
else if (osszeg < toCreate)
{
return -1;
}
else
{
return 1;
}
}
Il codice funziona correttamente (per quanto ne so) ma è troppo lento. Ci vogliono circa 3 secondi per risolvere l'esempio e ci possono essere 10000 numeri da 100 numeri.
Sono corretto supponendo che i numeri in un set siano coprime l'uno rispetto all'altro? – Valentin
Mi sembra che potresti eliminare un bel po 'di risposte potenziali facendo un po' di matematica iniziale per ogni numero. Sai ad esempio che quando aggiungi solo un numero devi solo controllare se il numero desiderato è divisibile per quel numero. Questo è un assegno piuttosto che un'iterazione su ogni numero possibile fino a superare il numero desiderato –
L'operatore modulo potrebbe essere tuo amico qui. Potresti iniziare facendo "1234567890% 68", quindi vedi se riesci a creare il resto con gli altri numeri più piccoli. Ciò lo trasformerebbe in un problema minore prima. –