Skocz do zawartości

[C++][Problem] 3 problemy przy kodowaniu


TRMC

Rekomendowane odpowiedzi

Siemka forumowicze i forumowiczki!

Otóż mam kilka problemów. Uczę się właśnie programowania z nauczycielem, który powiedział mi, że jak czegoś nie umiem zrobić, to mam pomocy szukać w internecie, a nie u niego. Dał mi on kilka zadań do zrobienia. Niestety nie wszystko umiem zrobić, a w internecie nie mogę znaleźć jakiś przydatnych/działających odpowiedzi :/ Dlatego chciałbym was poprosić o pomoc w pisaniu kilku patentów potrzebnych do tych programów.

 

1. Mam tablicę dwuwymiarową (wymiary mają tą samą wartość: tablica[z][z]) int i każda komórka ma swoją wartość. Problem polega na tym, że przy liczbie x ruchów mogę "wziąć" liczbę z pierwszego wymiaru o indeksie z, a potem z drugiego wymiaru o indeksie z (czyli najpierw biorę wartość z tablica[z], a potem z tablica[z][z]) i w tych x ruchach mam "wziąć" takie liczby, żeby ich suma była najwyższa możliwa.

Input:
<z> <x>

<z liczb oddzielonych spacjami jako pierwszy wymiar>

<z liczb oddzielonych spacjami jako drugi wymiar>

Output:

<suma>

 

2. Mam liczbę x i muszę sprawdzić, czy liczba ta jest potęgą dwójki. Próbowałem kodów znalezionych w necie, ale żaden nie działał o dziwo...

 

3. Tutaj to już troszkę wyższa szkoła jazdy, więc żeby było prościej to zacznę od dupy strony:
Input:

<x> <y>

<x startu> <y startu> <x mety> <y mety>

<w x wierszach po y znaków wpisujemy 'obrazek' składający się z dwóch różnych znaków albo '+' albo '-', np dla x=3, y=9 (spacje użyte są tylko do poprawienia czytelności, w czystym inpucie ich nie będzie):

+ - - + + + - + -

+ - - + - + - + -

+ + - + + + - + +

>

Output:

<liczba specjalych ruchów>

I teraz do sedna: cały sens programu polega na tym, że '-' to pole pełne, a '+' to pole puste i trzeba przejść z współrzędnych xy startu do xy mety, zakładając, że oba punkty oznaczają pola pełne. Specjalne ruchy to inaczej liczba 'nadepnięć' na puste pole, liczba ta ma być jak najmniejsza. Ruchów nie można wykonywać na ukos i w przypadku, gdy mamy np obrazek taki:

+ -

- +

czyli nie możemy się przedostać z jednego punktu do drugiego, output ma być równy -1

 

Uffff... wreszcie koniec, to wszystko na ten czas, ale raczej nowych problemów nie będzie :P Chętnie przeczytam i sprawdzę każdą pomoc. Jak wam się chce pisać kody, to byłbym wdzięczny, jeśli nie, to chociaż napiszcie jakiej biblioteki, funkcji itp. użyć :) z góry dziękuję za pomoc :D

Odnośnik do komentarza
Udostępnij na innych stronach

Masz dziwnego nauczyciela. I ujowego, bo wymaga a nie pomaga.

Ale do rzeczy.

 

masz tablicę kwadratową która przedstawia się np w taki sposób

 84 32 54 66 32
 82 44 30 50 21
 93 50 81 43 12
 02 84 97 21 45
 68 34 74 32 35
I masz z niej wyciągnąć liczbę w x ruchach?

Jedną z metod jest sprawdzanie czy każdy element tablicy jest większy od któregoś z poprzednich. Czyli pętle zagnieżdżone i porównywanie. Kod w spoilerze.

 

 

#include <cstdio>
#include <conio.h>

int main()
{
	int liczby[5][5] = {
		{5,32,96,32,44},
		{12,54,67,20,58},
		{81,50,3,666,49},
		{342,54,643,32},
		{93,56,345,463,33}
	};

	int max = 0;
	for(int a = 0; a < 5; a++)
		for(int b = 0; b < 5; b++)
			if (liczby[a][b] > max) max = liczby[a][b];

		printf("Najwieksza liczba: %i", max);
		_getch();
}

 

 

Jednak jeśli gościowi chodziło o ograniczoną ilość ruchów, to nie mam pojęcia jak to zrobić.

 

Numer 2:

Potęgowanie dwójek. Jeśli uczyłeś się kiedyś kodu dwójkowego, to pewnie wiesz że każde miejsce w lewo w jakiejś cyfrze dwójkowej to wartość kolejnej potęgi dwójki, np.

11001 = 2^0 + 2^3 + 2^4 = 1 + 8 + 16 = 25

 

Czyli np.

1 = 1

10 = 2

100 = 4

1000 = 8

10000 = 16

itd.

 

Możemy to rozwiązać na dwa sposoby. Albo korzystając z AND albo z przesunięcia bitowego.

metoda z AND:

 

skoro potęga 2 np. 16 wygląda tak:

10000

 

to odejmując 1 od niej, wychodzi nam 15, czyli takie coś:

01111

 

Jeśli zANDujemy takie liczby, to wychodzi nam na każdym bicie 0, ponieważ AND zwraca 1 jeśli dwie wrzucone do niego wartości wynoszą 1.

10000 - 16

01111 - 15

00000 - AND

 

Kiedy liczba nie jest potęgą 2, czyli np. 14

1110

to po odjęciu od niej 1 będzie tak wyglądać:

1101

i AND zwróci nam takie coś

1100

czyli liczba nie jest potęgą 2.

 

Ale z tym jest trochę zabawy, więc z naszego punktu widzenia przesunięcie bitowe jest prostsze.

 

Przesunięcie bitowe to operacja która przesuwa nam bity danej cyfry w daną stronę.

Na przykład

001101 >> 2 (przesunięcie w prawo o 2 bity) = 000011

albo 10010 << 3 (przesunięcie w lewo o 3 bity) = 10010000

 

Czyli używając przesunięcia w lewo możemy obliczać kolejne potęgi 2.

Musimy tylko sprawdzać czy nasza liczba = któraś z nich i voila.

 

Spróbuj sam napisać kod, jak nie to masz w spoilerze mój (co prawda nieco zamieszany, ale jakiś):

 

 

#include <conio.h>
#include <cstdio>

int main();
int PotegaDwa(int liczba);

int main()
{
	int numerek;
	scanf("%i", &numerek);
	printf("\n%i", PotegaDwa(numerek));
	_getch();
	return 0;
}

int PotegaDwa(int liczba)
{
	int spr = 1;
	for (int i = 0; i < 32; i++) //32 bo więcej bitów w int się nie zmieści pod procesorem x86
	{
		if(liczba == spr)
			return i;
		//printf("\n%i", liczba); //debug
		spr = spr << 1;
	}
	return 0;
}

 

 

Trzecie jest ostro zryte, jakoś nie mam ochoty się za nie brać. Logika gierek konsolowych.

846331404756772371599.jpeg
Odnośnik do komentarza
Udostępnij na innych stronach

Ale z tym jest trochę zabawy, więc z naszego punktu widzenia przesunięcie bitowe jest prostsze.

x&(x-1) jest metodą najprostszą do wykonania, prostą do zrozumienia i najszybszą IMO.
Odnośnik do komentarza
Udostępnij na innych stronach

Sopel, nie wiedzieć czemu nie chciało mi działać. Spróbuję jeszcze raz.

 

działa, widocznie ja coś zwaliłem :/

kod metody z AND:

 

#include <conio.h>
#include <cstdio>

int main();
bool PotegaDwa(int liczba);

int main()
{
	int numerek;
	scanf("%i", &numerek);
	printf("\n%i", PotegaDwa(numerek));
	_getch();
	return 0;
}

bool PotegaDwa(int liczba)
{
	if (liczba != 0 && !(liczba&(liczba-1))) // & = AND, negacja (!) ponieważ wynik AND'a wynosi 0 jeśli liczba jest potęgą 2.
		return true;
	else
		return false;
}
Tyle że metoda z przesunięciem przy okazji pokazuje którą potęgą 2 jest podana cyfra (logartm ;o).
846331404756772371599.jpeg
Odnośnik do komentarza
Udostępnij na innych stronach

for(c=0;c<T;c++){
s=tablica[c];
bool PotegaDwa(s);
p = PotegaDwa;
if (p == true)
cout<<"NIE\n";
else
cout<<"TAK\n";
}

 

co tutaj nie pasuje? bo wiem, że coś spie***yłem, a jakoś nie widzę błędu ;d wynik zawsze daje mi potęgę 2 :P

 

pewno mnie stłuczecie za te herezje, ale dopiero się uczę :P

Odnośnik do komentarza
Udostępnij na innych stronach

"Próbowałem kodów znalezionych w necie, ale żaden nie działał o dziwo..."

I call your bullshit and raise you on it.

 

http://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/

 

Tutaj masz dziesięć kolejnych sposobów do sprawdzenia.

 

Jeśli twój "nauczyciel" doradzał ci szukania pomocy w internecie, jestem pewny, że nie chodziło mu o zakładanie wątku na forum, tylko szukanie już dostępnych informacji, zwłaszcza tak banalnych. Musisz nauczyć się korzystać z szukajek internetowych, by znajdować potrzebne informacje.

Inna sprawa, że jeśli twój "nauczyciel" każe ci szukać jakichkolwiek informacji ze stanem wiedzy prezentowanym w powyższym poście, to nie jest to dobry nauczyciel. Nie opanowałeś nawet podstaw.

 

Najważniejsza rzecz, jaką musisz zrobić przed zamieszczeniem kodu na forum, to zaprezentowanie go w najkrótszej możliwej, kompilowalnej postaci. Nie dość, że prezentowany wycinek się nie kompiluje, to jeszcze nie zamieściłeś definicji funkcji PotegaDwa. Ponieważ zakładam, że gdzieś w kodzie masz zdefiniowaną funkcję, która sprawdza, czy przekazany int jest 2^n.

 

Więc, co tak naprawdę robisz tutaj:

 

 

bool PotegaDwa(s);
p = PotegaDwa;

 

Nie jest wywołaniem funkcji PotegaDwa.

 

"bool PotegaDwa(s);":

- deklaruje NOWĄ ZMIENNĄ

- typu bool

- o nazwie 'PotegaDwa'

- inicjalizuje ją wartością 's'

 

"bool PotegaDwa(s);" jest równoważne z "bool PotegaDwa = s;"

Są to dwa równoważne sposoby inicjalizacji zmiennych

 

Natomiast "p=PotegaDwa;":

- przypisuje do zmiennej 'p' wartość zmiennej 'PotegaDwa'

 

Jak się domyślam, chciałbyś do zmiennej p przypisać wartość ZWRACANĄ przez funkcję PotegaDwa, wywołaną z argumentem 's'. Należy zrobić to w ten sposób:

"p = PotegaDwa(s);"

 

Generalnie TYP ( bool, int, etc. ) podajesz WYŁĄCZNIE przy deklaracji ( definicji ) funkcji lub zmiennej. Nigdy przy wywoływaniu.


PS
Czy ty naprawdę masz zadanie z wyszukiwania ścieżki, kiedy nie potrafisz wywołać funkcji?

Ta sygnatura jest pusta.

Odnośnik do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

  • Ostatnio przeglądający forum [C++][Problem] 3 problemy przy kodowaniu   0 użytkowników
    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...