[shkola] redica
- From: Rangel Dokov <rangel_dokov@xxxxxx>
- To: shkola@xxxxxxxxxxxxx
- Date: Tue, 21 Oct 2003 18:56:06 +0300
Eto vi kod za namirane na naj-dylga rastqshta redica. S malki modifikacii
mozhe da se dokara do nenamalqvashta redica, no shte gi ostavq za uprazhnenie
(hint: nqma da stane ako prosto smenite `<' sys '<=' i '>' sys '>=' ;-)
--
Rangel Dokov
#include <stdio.h>
#define MAXN 100
// vryshta po-golqmoto ot 2 chisla
// za paskalistite da kazha che operatora `?:' si e chisto
// i prosto edin `if' napisan s po-malko simvoli ;-)
#define MAX(a,b) ( (a)>(b)?(a):(b) )
// tova mi e redicata ot chisla kakto mi e dadena
int str[MAXN];
// broj na elementite;
int count;
// v tozi masiv se zapisva naj-dobriq (t.e. naj-malkiq) kraj na redica
// s dylzhina `n'
int best_end[MAXN];
int best; // posledniq element na gorniq masiv kojto ne e 0
// tuk se zapisva poziciqta v redicata na koqto se namira tozi naj-dobyr
// kraj
int pos[MAXN];
// a tova pokazva roditelq na vseki element v naj-dobrata redica
// zavyrshasta s tozi element
int parent[MAXN];
void solve() {
int i, l, r, m;
best = 1;
best_end[1] = str[1];
pos[1] = 1;
for (i = 2; i <= count; i++) {
// standartno dvoichno tyrsene
// tyrsim str[i] v masiva best_end
l = 1; r = best; m = 1;
while (l < r) {
m = (l+r)/2;
if (best_end[m] == str[i])
break;
if (best_end[m] < str[i])
l = ++m;
else
r = --m;
}
// kraj na standartnoto dvoichno tyrsene
// tuk ima tri sluchaq za tova kyde ni e
// ostavilo dvoichnoto tyrsene. Mislq che e qsno
// ot if-ovete koi sa te
if (best_end[m] == str[i])
parent[i] = parent[pos[m]];
else if (best_end[m] > str[i] &&
((m == 1) || (best_end[m-1] < str[i]))) {
// pos[0] e neizpolzvan element => pos[0] = 0
// m == 1 ne e specialen sluchaj
parent[i] = pos[m-1];
best_end[m] = str[i];
pos[m] = i;
} else if (best_end[m] < str[i] &&
((m == best) || (best_end[m+1] > str[i]))) {
parent[i] = pos[m];
best_end[m+1] = str[i];
pos[m+1] = i;
best = MAX(best, m+1);
}
}
}
/*
fomat na vhoda:
1 red sydyrzha edno chislo N - broq na chislata.
sledvashtite `N' reda sydyrzhat po edno chislo
*/
void input() {
int i;
scanf("%d", &count);
for (i = 1; i <= count; i++)
scanf("%d", &str[i]);
}
/*
naj-dylgata redica trqbva da se izvede na edin red sys po edin
interval mezhdu vseki 2 chisla.
*/
void print(int p) {
if (parent[p] > 0)
print(parent[p]);
else {
printf("%d", str[p]);
return;
}
// slagame po edno intervalche predi vsqko chislo
// (bez pyrvoto koeto se izvezhda s gorniq printf)
printf(" %d", str[p]);
}
void output() {
print(pos[best]);
printf("\n");
}
int main() {
input();
solve();
output();
return 0;
}
Other related posts: