First Responder¶
Napisati program koji obrađuje podatke o dostupnosti vatrogasnih društava u slučaju požara. Podaci su zadati u ulaznoj datoteci u sledećem formatu:
mesto (jedna reč, do 30 karaktera)
geografska_sirina (realna vrednost)
geografska_duzina (realna vrednost)
Učitati podatke o vatrogasnim društvima u statički niz od 30 elemenata, koji će biti dostupni u slučaju požara. Nakon učitanih podataka, program učitava geografsku širinu i dužinu lokacije gde se dogodio požar, kao i kategoriju požara. U zavisnosti od ozbiljnosti požara, definišu se tri kategorije u odnosu na mesto dešavanja požara:
Žuta (Z): angažuju se sve vatrogasne stanice u krugu poluprečnika od 5km vazdušnom linijom
Narandžasta (N): angažuju se sve vatrogasne stanice u krugu poluprečnika od 10km vazdušnom linijom
Crvena (C): angažuju se sve vatrogasne stanice u krugu poluprečnika od 20km vazdušnom linijom
Rastojanje između dve tačke na Zemlji određuje se Haversinusnom formulom (data je u nastavku teksta). Ispisati sva vatrogasna društva koja će biti zahvaćena krugom. U ispis se računaju mesta i vazdušne razdaljine u kilometrima dobijeno korišćenjem Haversinusne formule. Ukoliko krug koji se formira oko lokacije požara ne obuhvata nijedno vatrogasno društvo, uzeti prvo najbliže izvan kruga.
Prilikom ispisa označiti tzv. "First responder-a", odnosno, vatrogasno društvo koje je očekivano da stigne najbrže na mesto incidenta. Dodati "(FR)" na string sa imenom mesta korišćenjem odgovarajuće funkcije za rad sa stringovima.
Korisne matematičke formule¶
Konverzija iz stepena u radijane
Haversinusna formula
Legenda korišćenih simbola:
φ1, φ2 = geografske širine u radijanima
λ1, λ2 = geografske dužine u radijanima
Δφ = φ2 - φ1
Δλ = λ2 - λ1
R = poluprecnik Zemlje ≈ 6371km
d = vazdušna razdaljina u kilometrima
U slučaju uspešnog izvršavanja programa, izaći sa status kodom 0 (EXIT_SUCCESS).
U slučaju nedovoljnog ili suvišnog broj argumenata komandne linije, izaći iz programa sa status kodom 1 (EXIT_FAILURE)
Primer ulazne datoteke vatrogasci.txt:
10
NoviSad 45.25911 19.84136
NoviSad 45.25933 19.84243
Petrovaradin 45.25454 19.86955
SrKamenica 45.22360 19.84423
Beocin 45.20785 19.71315
Futog 45.23843 19.70290
Rumenka 45.29567 19.74313
Temerin 45.40310 19.88465
Kac 45.30150 19.93775
Budisava 45.28354 19.98786
Primer poziva programa:
./a.out 45.25388 19.85194 Z < vatrogasci.txt
Primer ispisa programa na standardni izlaz:
Unesite broj vatrogasnih drustava:
1. vatrogasno drustvo:
2. vatrogasno drustvo:
3. vatrogasno drustvo:
4. vatrogasno drustvo:
5. vatrogasno drustvo:
6. vatrogasno drustvo:
7. vatrogasno drustvo:
8. vatrogasno drustvo:
9. vatrogasno drustvo:
10. vatrogasno drustvo:
NoviSad 1.01km
NoviSad(FR) 0.96km
Petrovaradin 1.38km
SrKamenica 3.42km
Primer poziva programa kad nema vatrogasnog društva u okolini:
./a.out 45.344119 19.857105 Z < vatrogasci.txt
Primer ispisa programa na standardni izlaz:
Unesite broj vatrogasnih drustava:
1. vatrogasno drustvo:
2. vatrogasno drustvo:
3. vatrogasno drustvo:
4. vatrogasno drustvo:
5. vatrogasno drustvo:
6. vatrogasno drustvo:
7. vatrogasno drustvo:
8. vatrogasno drustvo:
9. vatrogasno drustvo:
10. vatrogasno drustvo:
Temerin(FR) 6.90km
Primer rešenja¶
1#include <stdio.h>
2#include <string.h>
3#include <math.h>
4#include <stdlib.h>
5
6#define MAX_MESTO 31
7
8#define MAX_SIZE 30
9
10#define R 6371.0
11
12typedef struct vatrogasci_st
13{
14 char mesto[MAX_MESTO];
15 double geografska_sirina;
16 double geografska_duzina;
17} VATROGASCI;
18
19void ucitaj_vatrogasna_drustva(VATROGASCI *v, int *pn);
20double domet_kategorije(char kategorija_pozara);
21double stepeni_u_radijane(double stepeni);
22double haversinusna_razdaljina(double geogr_sirina1, double geogr_duzina1, double geogr_sirina2, double geogr_duzina2);
23void ispisi_angazovana_vatrogasna_drustva(
24 VATROGASCI *v, int n, double geografska_sirina_pozara, double geografska_duzina_pozara, double poluprecnik);
25
26int main(int argc, char **argv)
27{
28 VATROGASCI vatrogasci[MAX_SIZE];
29 int n;
30
31 if(argc != 4)
32 {
33 printf("Primer poziva: %s 45.25388 19.85194 Z < vatrogasci.txt\n", argv[0]);
34 exit(EXIT_FAILURE);
35 }
36
37 ucitaj_vatrogasna_drustva(vatrogasci, &n);
38
39 double geografska_sirina_pozara = atof(argv[1]);
40 double geografska_duzina_pozara = atof(argv[2]);
41 char kategorija_pozara = argv[3][0];
42
43 double poluprecnik = domet_kategorije(kategorija_pozara);
44
45 printf("\n\n");
46 ispisi_angazovana_vatrogasna_drustva(vatrogasci, n, geografska_sirina_pozara, geografska_duzina_pozara, poluprecnik);
47
48 return EXIT_SUCCESS;
49}
50
51void ucitaj_vatrogasna_drustva(VATROGASCI *v, int *pn)
52{
53 int i;
54
55 do
56 {
57 printf("Unesite broj vatrogasnih drustava: ");
58 scanf("%d", pn);
59 } while (*pn <= 0 || *pn > MAX_SIZE);
60
61 for(i = 0;i < *pn;i++)
62 {
63 printf("\n%d. vatrogasno drustvo: ", i + 1);
64 scanf("%s %lf %lf", v[i].mesto, &v[i].geografska_sirina, &v[i].geografska_duzina);
65 }
66}
67
68double domet_kategorije(char kategorija_pozara)
69{
70 switch(kategorija_pozara)
71 {
72 case 'Z':
73 return 5.0;
74 case 'N':
75 return 10.0;
76 case 'C':
77 return 20.0;
78 }
79
80 return 0.0;
81}
82
83double stepeni_u_radijane(double stepeni)
84{
85 return stepeni * M_PI / 180;
86}
87
88double haversinusna_razdaljina(double geogr_sirina1, double geogr_duzina1, double geogr_sirina2, double geogr_duzina2)
89{
90 double fi1 = stepeni_u_radijane(geogr_sirina1);
91 double fi2 = stepeni_u_radijane(geogr_sirina2);
92
93 double delta_fi = stepeni_u_radijane(geogr_sirina2 - geogr_sirina1);
94 double delta_lambda = stepeni_u_radijane(geogr_duzina2 - geogr_duzina1);
95
96 double a = pow(sin(delta_fi / 2), 2) +
97 cos(fi1) * cos(fi2) *
98 pow(sin(delta_lambda / 2), 2);
99
100 double c = 2 * atan2(sqrt(a), sqrt(1 - a));
101
102 return R * c;
103}
104
105void ispisi_angazovana_vatrogasna_drustva(
106 VATROGASCI *v, int n, double geografska_sirina_pozara, double geografska_duzina_pozara, double poluprecnik)
107{
108 int i, indeks_najblizeg = 0;
109 double vazdusne_razdaljine[MAX_SIZE], najbliza_razdaljina = haversinusna_razdaljina(
110 v[0].geografska_sirina, v[0].geografska_duzina, geografska_sirina_pozara, geografska_duzina_pozara);;
111
112 for(i = 0;i < n;i++)
113 {
114 vazdusne_razdaljine[i] = haversinusna_razdaljina(
115 v[i].geografska_sirina, v[i].geografska_duzina, geografska_sirina_pozara, geografska_duzina_pozara);
116
117 if(vazdusne_razdaljine[i] < najbliza_razdaljina)
118 {
119 najbliza_razdaljina = vazdusne_razdaljine[i];
120 indeks_najblizeg = i;
121 }
122 }
123
124 int ima_u_poluprecniku = 0;
125
126 for(i = 0;i < n;i++)
127 {
128 if(indeks_najblizeg == i)
129 {
130 strcat(v[i].mesto, "(FR)");
131 }
132
133 if(vazdusne_razdaljine[i] <= poluprecnik)
134 {
135 printf("%s %.2lfkm\n", v[i].mesto, vazdusne_razdaljine[i]);
136 ima_u_poluprecniku = 1;
137 }
138 }
139
140 if(ima_u_poluprecniku == 0)
141 {
142 printf("%s %.2lfkm\n", v[indeks_najblizeg].mesto, vazdusne_razdaljine[indeks_najblizeg]);
143 }
144}