Browse Source

Adaugare MULTE probleme infoarena

master
Matei-Alexandru Gardus 4 months ago
parent
commit
ca2110773f
No known key found for this signature in database

+ 6
- 0
infoarena/CMakeLists.txt View File

@@ -5,14 +5,20 @@ project("infoarena")
5 5
 add_subdirectory("atac")
6 6
 add_subdirectory("asmax")
7 7
 add_subdirectory("bemo")
8
+add_subdirectory("capitala")
8 9
 add_subdirectory("cautbin")
9 10
 add_subdirectory("diametru")
10 11
 add_subdirectory("dfs")
12
+add_subdirectory("energii")
13
+add_subdirectory("graf")
11 14
 add_subdirectory("heapuri")
12 15
 add_subdirectory("jap2")
16
+add_subdirectory("jocul")
13 17
 add_subdirectory("mexitate")
14 18
 add_subdirectory("petrol")
19
+add_subdirectory("plantatie")
15 20
 add_subdirectory("rmq")
21
+add_subdirectory("rucsac")
16 22
 add_subdirectory("sortaret")
17 23
 add_subdirectory("stramosi")
18 24
 add_subdirectory("teatru")

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

@@ -0,0 +1,7 @@
1
+CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)
2
+
3
+get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
4
+string(REPLACE " " "_" ProjectId ${ProjectId})
5
+project(${ProjectId})
6
+
7
+add_executable(${PROJECT_NAME} main.cpp)

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

@@ -0,0 +1,50 @@
1
+#include <fstream>
2
+#include <vector>
3
+#include <queue>
4
+#include <algorithm>
5
+#define NMAX 100001
6
+
7
+using namespace std;
8
+
9
+ifstream fin("capitala.in");
10
+ofstream fout("capitala.out");
11
+
12
+int N;
13
+
14
+bool vizitat[NMAX];
15
+
16
+vector<int> v[NMAX];
17
+queue coada;
18
+
19
+void bfs(int nod)
20
+{
21
+	vizitat[nod] = true;
22
+	coada.push(nod);
23
+	while (!coada.empty())
24
+	{
25
+		int nodCurent = coada.front();
26
+		sort(v[nodCurent].begin(), v[nodCurent].end());
27
+		coada.pop();
28
+		for (int i = 0; i < v[nodCurent].size(); ++i)
29
+		{
30
+			if (!vizitat[v[nodCurent][i]])
31
+			{
32
+				vizitat[v[nodCurent][i]] = true;
33
+				coada.push(v[nodCurent][i]);
34
+				fout << v[nodCurent][i] << " ";
35
+			}
36
+		}
37
+	}
38
+}
39
+
40
+int main() {
41
+    fin >> N;
42
+    for(int i = 1; i <= N; i++) {
43
+        int x, y;
44
+        fin >> x >> y;
45
+        v[x].push_back(y);
46
+        v[y].push_back(x);
47
+    }
48
+
49
+    
50
+}

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

@@ -0,0 +1,7 @@
1
+CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)
2
+
3
+get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
4
+string(REPLACE " " "_" ProjectId ${ProjectId})
5
+project(${ProjectId})
6
+
7
+add_executable(${PROJECT_NAME} main.cpp)

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

@@ -0,0 +1,55 @@
1
+#include <fstream>
2
+#define NMAX 5001
3
+#define GMAX 10001
4
+#define INF 1000000000
5
+
6
+using namespace std;
7
+
8
+ifstream fin("energii.in");
9
+ofstream fout("energii.out");
10
+
11
+/** "Energii"
12
+ * 
13
+ *  Literalmente problema rucsac, doar că verifici minimum din vectorul de dinamică.
14
+ *
15
+ */
16
+
17
+int N,                // numărul de obiecte disponibile
18
+    G,                // greutatea maximă admisibilă ghiozdanului
19
+    w[NMAX],          // greutatea fiecărui obiect
20
+    p[NMAX],          // profitul fiecărui obiect
21
+    profit[GMAX + 1]; // profitul maxim care se poate obține cu obiecte care au suma greutăților = j
22
+
23
+int main() {
24
+    fin >> N >> G;
25
+    for (int i = 1; i <= N; i++) {
26
+        fin >> w[i] >> p[i];
27
+    }
28
+
29
+    profit[0] = 0;
30
+
31
+    for (int j = 1; j <= GMAX; j++) {
32
+        profit[j] = INF;
33
+    }
34
+    for (int i = 1; i <= N; i++) {
35
+        for(int j = GMAX; j >= w[i]; j--) {
36
+            if (profit[j] > profit[j - w[i]] + p[i]) {
37
+                profit[j] = profit[j - w[i]] + p[i];
38
+            }
39
+        }
40
+    }
41
+
42
+    int sol = INF;
43
+    for (int i = G; i <= GMAX; i++) {
44
+        if (sol > profit[i]) {
45
+            sol = profit[i];
46
+        }
47
+    }
48
+
49
+    if (sol == INF) {
50
+        fout << -1;
51
+    } else {
52
+        fout << sol;
53
+    }
54
+    return 0;
55
+}

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

@@ -0,0 +1,7 @@
1
+CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)
2
+
3
+get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
4
+string(REPLACE " " "_" ProjectId ${ProjectId})
5
+project(${ProjectId})
6
+
7
+add_executable(${PROJECT_NAME} main.cpp)

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

@@ -0,0 +1,88 @@
1
+#include <fstream>
2
+#include <vector>
3
+#include <queue>
4
+#include <algorithm>
5
+#define NMAX 7501
6
+
7
+using namespace std;
8
+
9
+ifstream fin("graf.in");
10
+ofstream fout("graf.out");
11
+
12
+/** Graf
13
+ * 
14
+ *  O problema de BFS, dar cu un pic de topping extra peste ea.
15
+ *  In esenta, avem doua BFS, cu distantele marcate in distantaX si distantaY. Apoi cautam cele care s-au gasit optime in BFS-ul original.
16
+ *  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.
17
+ *  Si gata!
18
+ */
19
+int N, M, X, Y,      // variabile cu semnificatia din enunt
20
+    distantaX[NMAX], // distanta de la oricare nod la X
21
+    distantaY[NMAX], // distanta de la oricare nod la Y
22
+    continuu[NMAX];  // vectorul in care tinem minte prin ce noduri poate parcurge calea optima
23
+
24
+bool vizitat[NMAX];  // vector de vizitare, necesar pentru BFS
25
+
26
+queue<int> coada;    // coada pentru BFS
27
+vector<int> v[NMAX]; // vector cu muchiile grafului
28
+vector<int> sol;     // nodurile cerute de problema
29
+
30
+void clean() {
31
+    coada.empty();
32
+    for (int i = 1; i <= NMAX - 1; i++) {
33
+        vizitat[i] = false;
34
+    }
35
+}
36
+
37
+void bfs(int nod, int distanta[]) {
38
+	vizitat[nod] = true;
39
+	coada.push(nod);
40
+	while (!coada.empty())
41
+	{
42
+		int nodCurent = coada.front();
43
+		sort(v[nodCurent].begin(), v[nodCurent].end());
44
+		coada.pop();
45
+		for (int i = 0; i < v[nodCurent].size(); ++i)
46
+		{
47
+			if (!vizitat[v[nodCurent][i]])
48
+			{
49
+				vizitat[v[nodCurent][i]] = true;
50
+				coada.push(v[nodCurent][i]);
51
+				distanta[v[nodCurent][i]] = distanta[nodCurent] + 1;
52
+			}
53
+		}
54
+	}
55
+}
56
+
57
+int main() {
58
+    fin >> N >> M >> X >> Y;
59
+    for (int i = 1; i <= M; i++) {
60
+        int x, y;
61
+        fin >> x >> y;
62
+        v[x].push_back(y);
63
+        v[y].push_back(x);
64
+    }
65
+    bfs(X, distantaX);
66
+    clean();
67
+    bfs(Y, distantaY);
68
+
69
+    for (int i = 1; i <= N; i++) {
70
+        if (distantaX[i] + distantaY[i] == distantaX[Y]) {
71
+            continuu[distantaX[i]]++;
72
+        }
73
+    }
74
+
75
+    for (int i = 1; i <= N; i++) {
76
+        if (continuu[distantaX[i]] == 1 && distantaX[i] + distantaY[i] == distantaX[Y]) {
77
+            sol.push_back(i);
78
+        }
79
+    }
80
+    fout << sol.size() << "\n";
81
+    sort(sol.begin(), sol.end());
82
+    
83
+    for (auto x : sol) {
84
+        fout << x << " ";
85
+    }
86
+
87
+    return 0;
88
+}

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

@@ -0,0 +1,7 @@
1
+CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)
2
+
3
+get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
4
+string(REPLACE " " "_" ProjectId ${ProjectId})
5
+project(${ProjectId})
6
+
7
+add_executable(${PROJECT_NAME} main.cpp)

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

@@ -0,0 +1,49 @@
1
+#include <fstream>
2
+#define NMAX 100001
3
+using namespace std;
4
+
5
+ifstream fin("jocul.in");
6
+ofstream fout("jocul.out");
7
+
8
+/** "Jocul"
9
+ * 
10
+ *  Problema rucsac, cu o mică modificare.
11
+ *  În esență, trebuie să facem un rucsac în care pur și simplu verificăm dacă se poate face un grup de lungime specifică,
12
+ *  până în lungimea tuturor bețișoarelor / 2.
13
+ */
14
+
15
+int N,       // numărul de bețișoare
16
+    lungime, // lungimea maximă posibilă cu toate bețișoarele
17
+    isImpar,   // dacă numărul este par
18
+    l[NMAX], // lungimea fiecărui bețișor
19
+    p[NMAX]; // dinamica, dacă se poate face un grup de lungime i de bețișoare
20
+
21
+int main() {
22
+    fin >> N;
23
+    for (int i = 1; i <= N; i++) {
24
+        fin >> l[i];
25
+        lungime += l[i];
26
+    }
27
+    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++
28
+        isImpar = 1;
29
+    }
30
+    lungime /= 2;
31
+    for (int i = 1; i <= lungime; i++) {
32
+        p[i] = -1;
33
+    }
34
+    for (int i = 1; i <= N; i++) {
35
+        for (int j = lungime - l[i]; j >= 0; j--) {
36
+            if (p[j] != -1) {
37
+                p[j + l[i]] = 1;
38
+            }
39
+        }
40
+    }
41
+
42
+    for (int i = lungime; i > 0; i--) {
43
+        if (p[i] == 1) {
44
+            fout << i << " " << 2 * lungime - i + isImpar;
45
+            break;
46
+        }
47
+    }
48
+    return 0;
49
+}

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

@@ -0,0 +1,7 @@
1
+CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)
2
+
3
+get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
4
+string(REPLACE " " "_" ProjectId ${ProjectId})
5
+project(${ProjectId})
6
+
7
+add_executable(${PROJECT_NAME} main.cpp)

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

@@ -0,0 +1,54 @@
1
+#include <fstream>
2
+
3
+#define NMAX 501
4
+#define LMAX 9
5
+
6
+int rmq[LMAX][NMAX][NMAX], lg[NMAX], n, m;
7
+
8
+using namespace std;
9
+
10
+ifstream fin("plantatie.in");
11
+ofstream fout("plantatie.out");
12
+
13
+/** Plantatie
14
+ * 
15
+ *  Plantatie este problema RMQ, generalizata pe 2D.
16
+ */
17
+int main() {
18
+    fin >> n >> m;
19
+
20
+    for (int i = 1; i <= n; i++) {
21
+        lg[i] = lg[i / 2] + 1;
22
+    }
23
+
24
+    for (int i = 1; i <= n; i++) {
25
+        for (int j = 1; j <= n; j++) {
26
+            fin >> rmq[0][i][j];
27
+        }
28
+    }
29
+
30
+    int l, p, x, y;
31
+	for(int k = 1; k <= lg[n]; k++) {
32
+        l = n - (1 << k) + 1;
33
+        p = 1 << (k - 1);
34
+        for(int i = 1; i <= l; i++) {
35
+            for(int j = 1; j <= l; j++) {
36
+                x = max(rmq[k - 1][i][j], rmq[k - 1][i + p][j + p]);
37
+                y = max(rmq[k - 1][i + p][j], rmq[k - 1][i][j + p]);
38
+                rmq[k][i][j] = max(x, y);
39
+            }
40
+        }
41
+    }
42
+
43
+    int i, j, k;
44
+    for (int q = 1; q <= m; q++) {
45
+        fin >> i >> j >> p;
46
+        k = lg[mic - 1];
47
+        mic -= 1 << k;
48
+        x = max(rmq[k][i][j], rmq[k][i + mic][j + mic]);
49
+	    y = max(rmq[k][i + mic][j], rmq[k][i][j + mic]);
50
+        fout << max(x, y) << '\n';        
51
+    }
52
+
53
+    return 0;
54
+}

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

@@ -0,0 +1,7 @@
1
+CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0)
2
+
3
+get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
4
+string(REPLACE " " "_" ProjectId ${ProjectId})
5
+project(${ProjectId})
6
+
7
+add_executable(${PROJECT_NAME} main.cpp)

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

@@ -0,0 +1,48 @@
1
+#include <fstream>
2
+#define NMAX 5001
3
+#define GMAX 10001
4
+
5
+using namespace std;
6
+
7
+ifstream fin("rucsac.in");
8
+ofstream fout("rucsac.out");
9
+
10
+/** "Rucsac"
11
+ * 
12
+ *  Aceasta este problema clasica a rucsacului, scrisă în programare dinamică.
13
+ *  Se poate găsi o descriere mai detaliată pe Wikipedia: https://en.wikipedia.org/wiki/Knapsack_problem
14
+ */
15
+
16
+int N,            // numărul de obiecte disponibile
17
+    G,            // greutatea maximă admisibilă ghiozdanului
18
+    w[NMAX],      // greutatea fiecărui obiect
19
+    p[NMAX],      // profitul fiecărui obiect
20
+    profit[GMAX]; // profitul maxim care se poate obține cu obiecte care au suma greutăților = j
21
+
22
+int main() {
23
+    fin >> N >> G;
24
+    for (int i = 0; i < N; i++) {
25
+        fin >> w[i] >> p[i];
26
+    }
27
+
28
+    for (int j = 1; j <= G; j++) {
29
+        profit[j] = -1;
30
+    }
31
+    for (int i = 0; i < N; i++) {
32
+        for(int j = G - w[i]; j >= 0; j--) {
33
+            if (profit[j] != -1 && profit[j] + p[i] > profit[j + w[i]]) {
34
+                profit[j + w[i]] = profit[j] + p[i];
35
+            }
36
+        }
37
+    }
38
+
39
+    int sol = 0;
40
+    for (int j = G; j >= 0; j--) {
41
+        if (sol < profit[j]) {
42
+            sol = profit[j];
43
+        }
44
+    }
45
+
46
+    fout << sol;
47
+    return 0;
48
+}

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

@@ -2,19 +2,19 @@
2 2
 #include <fstream>
3 3
 #include <vector>	
4 4
 #include <queue>
5
+#define N 50001
6
+#define M 100001
5 7
 
6 8
 using namespace std;
7 9
 
8 10
 ifstream fin("sortaret.in");	
9 11
 ofstream fout("sortaret.out");
10
-	
11
-const int N = 50001, M = 100001;
12
-
13
-vector <int> a[N];
14
-
15
-int pred[N], stopol[N], nr;
16 12
 
17
-bool viz[N];
13
+int pred[N],       // lista de predecesori, fiecare nod ține aici tatăl său
14
+    stopol[N],     // lista simplă înlănțuită pentru sortare topologică
15
+    nr;            // numărul de elemente din lista "stopol"
16
+vector <int> a[N]; // lista de adiacență, fiecare nod ține în acest vector succesorii săi
17
+bool viz[N];       // vectorul de vizitare al fiecărui nod
18 18
 
19 19
 void dfs(int x)
20 20
 {	

Loading…
Cancel
Save