Browse Source

Adaugare MULTE probleme infoarena

master
Matei-Alexandru Gardus 7 months ago
parent
commit
ca2110773f
Signed by: StormFireFox1 <matei@gardus.eu> GPG Key ID: F3D2B830AB9B94AA

+ 6
- 0
infoarena/CMakeLists.txt View File

@@ -5,14 +5,20 @@ project("infoarena")
add_subdirectory("atac")
add_subdirectory("asmax")
add_subdirectory("bemo")
add_subdirectory("capitala")
add_subdirectory("cautbin")
add_subdirectory("diametru")
add_subdirectory("dfs")
add_subdirectory("energii")
add_subdirectory("graf")
add_subdirectory("heapuri")
add_subdirectory("jap2")
add_subdirectory("jocul")
add_subdirectory("mexitate")
add_subdirectory("petrol")
add_subdirectory("plantatie")
add_subdirectory("rmq")
add_subdirectory("rucsac")
add_subdirectory("sortaret")
add_subdirectory("stramosi")
add_subdirectory("teatru")

+ 7
- 0
infoarena/capitala/CMakeLists.txt View File

@@ -0,0 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)

get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId})

add_executable(${PROJECT_NAME} main.cpp)

+ 50
- 0
infoarena/capitala/main.cpp View File

@@ -0,0 +1,50 @@
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#define NMAX 100001

using namespace std;

ifstream fin("capitala.in");
ofstream fout("capitala.out");

int N;

bool vizitat[NMAX];

vector<int> v[NMAX];
queue coada;

void bfs(int nod)
{
vizitat[nod] = true;
coada.push(nod);
while (!coada.empty())
{
int nodCurent = coada.front();
sort(v[nodCurent].begin(), v[nodCurent].end());
coada.pop();
for (int i = 0; i < v[nodCurent].size(); ++i)
{
if (!vizitat[v[nodCurent][i]])
{
vizitat[v[nodCurent][i]] = true;
coada.push(v[nodCurent][i]);
fout << v[nodCurent][i] << " ";
}
}
}
}

int main() {
fin >> N;
for(int i = 1; i <= N; i++) {
int x, y;
fin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}

}

+ 7
- 0
infoarena/energii/CMakeLists.txt View File

@@ -0,0 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)

get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId})

add_executable(${PROJECT_NAME} main.cpp)

+ 55
- 0
infoarena/energii/main.cpp View File

@@ -0,0 +1,55 @@
#include <fstream>
#define NMAX 5001
#define GMAX 10001
#define INF 1000000000

using namespace std;

ifstream fin("energii.in");
ofstream fout("energii.out");

/** "Energii"
*
* Literalmente problema rucsac, doar că verifici minimum din vectorul de dinamică.
*
*/

int N, // numărul de obiecte disponibile
G, // greutatea maximă admisibilă ghiozdanului
w[NMAX], // greutatea fiecărui obiect
p[NMAX], // profitul fiecărui obiect
profit[GMAX + 1]; // profitul maxim care se poate obține cu obiecte care au suma greutăților = j

int main() {
fin >> N >> G;
for (int i = 1; i <= N; i++) {
fin >> w[i] >> p[i];
}

profit[0] = 0;

for (int j = 1; j <= GMAX; j++) {
profit[j] = INF;
}
for (int i = 1; i <= N; i++) {
for(int j = GMAX; j >= w[i]; j--) {
if (profit[j] > profit[j - w[i]] + p[i]) {
profit[j] = profit[j - w[i]] + p[i];
}
}
}

int sol = INF;
for (int i = G; i <= GMAX; i++) {
if (sol > profit[i]) {
sol = profit[i];
}
}

if (sol == INF) {
fout << -1;
} else {
fout << sol;
}
return 0;
}

+ 7
- 0
infoarena/graf/CMakeLists.txt View File

@@ -0,0 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)

get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId})

add_executable(${PROJECT_NAME} main.cpp)

+ 88
- 0
infoarena/graf/main.cpp View File

@@ -0,0 +1,88 @@
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#define NMAX 7501

using namespace std;

ifstream fin("graf.in");
ofstream fout("graf.out");

/** Graf
*
* O problema de BFS, dar cu un pic de topping extra peste ea.
* In esenta, avem doua BFS, cu distantele marcate in distantaX si distantaY. Apoi cautam cele care s-au gasit optime in BFS-ul original.
* Notam caile continue prin cost in continuu[i], si apoi facem din nou o iteratie ca inainte, vedem printre care dintre ele am mai trecut.
* Si gata!
*/
int N, M, X, Y, // variabile cu semnificatia din enunt
distantaX[NMAX], // distanta de la oricare nod la X
distantaY[NMAX], // distanta de la oricare nod la Y
continuu[NMAX]; // vectorul in care tinem minte prin ce noduri poate parcurge calea optima

bool vizitat[NMAX]; // vector de vizitare, necesar pentru BFS

queue<int> coada; // coada pentru BFS
vector<int> v[NMAX]; // vector cu muchiile grafului
vector<int> sol; // nodurile cerute de problema

void clean() {
coada.empty();
for (int i = 1; i <= NMAX - 1; i++) {
vizitat[i] = false;
}
}

void bfs(int nod, int distanta[]) {
vizitat[nod] = true;
coada.push(nod);
while (!coada.empty())
{
int nodCurent = coada.front();
sort(v[nodCurent].begin(), v[nodCurent].end());
coada.pop();
for (int i = 0; i < v[nodCurent].size(); ++i)
{
if (!vizitat[v[nodCurent][i]])
{
vizitat[v[nodCurent][i]] = true;
coada.push(v[nodCurent][i]);
distanta[v[nodCurent][i]] = distanta[nodCurent] + 1;
}
}
}
}

int main() {
fin >> N >> M >> X >> Y;
for (int i = 1; i <= M; i++) {
int x, y;
fin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
bfs(X, distantaX);
clean();
bfs(Y, distantaY);

for (int i = 1; i <= N; i++) {
if (distantaX[i] + distantaY[i] == distantaX[Y]) {
continuu[distantaX[i]]++;
}
}

for (int i = 1; i <= N; i++) {
if (continuu[distantaX[i]] == 1 && distantaX[i] + distantaY[i] == distantaX[Y]) {
sol.push_back(i);
}
}
fout << sol.size() << "\n";
sort(sol.begin(), sol.end());
for (auto x : sol) {
fout << x << " ";
}

return 0;
}

+ 7
- 0
infoarena/jocul/CMakeLists.txt View File

@@ -0,0 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)

get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId})

add_executable(${PROJECT_NAME} main.cpp)

+ 49
- 0
infoarena/jocul/main.cpp View File

@@ -0,0 +1,49 @@
#include <fstream>
#define NMAX 100001
using namespace std;

ifstream fin("jocul.in");
ofstream fout("jocul.out");

/** "Jocul"
*
* Problema rucsac, cu o mică modificare.
* În esență, trebuie să facem un rucsac în care pur și simplu verificăm dacă se poate face un grup de lungime specifică,
* până în lungimea tuturor bețișoarelor / 2.
*/

int N, // numărul de bețișoare
lungime, // lungimea maximă posibilă cu toate bețișoarele
isImpar, // dacă numărul este par
l[NMAX], // lungimea fiecărui bețișor
p[NMAX]; // dinamica, dacă se poate face un grup de lungime i de bețișoare

int main() {
fin >> N;
for (int i = 1; i <= N; i++) {
fin >> l[i];
lungime += l[i];
}
if (lungime % 2 == 1) { // dacă lungimea maximă e impară, trebuie adăugat un 1 mai târziu, să compensăm că îl rotunjește C++
isImpar = 1;
}
lungime /= 2;
for (int i = 1; i <= lungime; i++) {
p[i] = -1;
}
for (int i = 1; i <= N; i++) {
for (int j = lungime - l[i]; j >= 0; j--) {
if (p[j] != -1) {
p[j + l[i]] = 1;
}
}
}

for (int i = lungime; i > 0; i--) {
if (p[i] == 1) {
fout << i << " " << 2 * lungime - i + isImpar;
break;
}
}
return 0;
}

+ 7
- 0
infoarena/plantatie/CMakeLists.txt View File

@@ -0,0 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)

get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId})

add_executable(${PROJECT_NAME} main.cpp)

+ 54
- 0
infoarena/plantatie/main.cpp View File

@@ -0,0 +1,54 @@
#include <fstream>

#define NMAX 501
#define LMAX 9

int rmq[LMAX][NMAX][NMAX], lg[NMAX], n, m;

using namespace std;

ifstream fin("plantatie.in");
ofstream fout("plantatie.out");

/** Plantatie
*
* Plantatie este problema RMQ, generalizata pe 2D.
*/
int main() {
fin >> n >> m;

for (int i = 1; i <= n; i++) {
lg[i] = lg[i / 2] + 1;
}

for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
fin >> rmq[0][i][j];
}
}

int l, p, x, y;
for(int k = 1; k <= lg[n]; k++) {
l = n - (1 << k) + 1;
p = 1 << (k - 1);
for(int i = 1; i <= l; i++) {
for(int j = 1; j <= l; j++) {
x = max(rmq[k - 1][i][j], rmq[k - 1][i + p][j + p]);
y = max(rmq[k - 1][i + p][j], rmq[k - 1][i][j + p]);
rmq[k][i][j] = max(x, y);
}
}
}

int i, j, k;
for (int q = 1; q <= m; q++) {
fin >> i >> j >> p;
k = lg[mic - 1];
mic -= 1 << k;
x = max(rmq[k][i][j], rmq[k][i + mic][j + mic]);
y = max(rmq[k][i + mic][j], rmq[k][i][j + mic]);
fout << max(x, y) << '\n';
}

return 0;
}

+ 7
- 0
infoarena/rucsac/CMakeLists.txt View File

@@ -0,0 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)

get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId})

add_executable(${PROJECT_NAME} main.cpp)

+ 48
- 0
infoarena/rucsac/main.cpp View File

@@ -0,0 +1,48 @@
#include <fstream>
#define NMAX 5001
#define GMAX 10001

using namespace std;

ifstream fin("rucsac.in");
ofstream fout("rucsac.out");

/** "Rucsac"
*
* Aceasta este problema clasica a rucsacului, scrisă în programare dinamică.
* Se poate găsi o descriere mai detaliată pe Wikipedia: https://en.wikipedia.org/wiki/Knapsack_problem
*/

int N, // numărul de obiecte disponibile
G, // greutatea maximă admisibilă ghiozdanului
w[NMAX], // greutatea fiecărui obiect
p[NMAX], // profitul fiecărui obiect
profit[GMAX]; // profitul maxim care se poate obține cu obiecte care au suma greutăților = j

int main() {
fin >> N >> G;
for (int i = 0; i < N; i++) {
fin >> w[i] >> p[i];
}

for (int j = 1; j <= G; j++) {
profit[j] = -1;
}
for (int i = 0; i < N; i++) {
for(int j = G - w[i]; j >= 0; j--) {
if (profit[j] != -1 && profit[j] + p[i] > profit[j + w[i]]) {
profit[j + w[i]] = profit[j] + p[i];
}
}
}

int sol = 0;
for (int j = G; j >= 0; j--) {
if (sol < profit[j]) {
sol = profit[j];
}
}

fout << sol;
return 0;
}

+ 7
- 7
infoarena/sortaret/main.cpp View File

@@ -2,19 +2,19 @@
#include <fstream>
#include <vector>
#include <queue>
#define N 50001
#define M 100001

using namespace std;

ifstream fin("sortaret.in");
ofstream fout("sortaret.out");
const int N = 50001, M = 100001;

vector <int> a[N];

int pred[N], stopol[N], nr;

bool viz[N];
int pred[N], // lista de predecesori, fiecare nod ține aici tatăl său
stopol[N], // lista simplă înlănțuită pentru sortare topologică
nr; // numărul de elemente din lista "stopol"
vector <int> a[N]; // lista de adiacență, fiecare nod ține în acest vector succesorii săi
bool viz[N]; // vectorul de vizitare al fiecărui nod

void dfs(int x)
{

Loading…
Cancel
Save