laporan tugas kelompok
TRANSCRIPT
LAPORAN TUGAS KELOMPOK
PAAL A
Oleh:
Aldy Ahsandin 5109100704
Mohammad Farid Naufal 5110100094
Ahmad Sodik 5110100125
JURUSAN TEKNIK INFORMATIKA
FAKULTAS TEKNOLOGI INFORMASI
INSTITUT TEKNOLOGI SEPULUH NOPEMBER
2012
Pembagian Pekerjaan
Aldy Ahsandin (5109100704)
1. Basic Routines
2. Buzz Trouble
Mohammad Farid Naufal (5110100094)
1. Collision Issue (CDC12_C)
2. Drastic Race (CDC12_D)
3. Halt the War (CDC12_H)
Ahmad Sodik
1. Innovative Combination (CDC12_1)
2. Forbidden Machine (CDC12_F)
SPOJ PROBLEM Basic Routines
Problem code: CDC12_C
Analisis
Testcase (simbol T)
Jumlah kegiatan ( simbol N)
Energi yang dimiliki Ronny (simbol E)
Aktivitas beserta energi yang dibutuhkan ( simbol A dan V)
Ketika akan mengerjakan problem ini, pemecahan yang terbayang adalah dengan menggunakan
Knapsack. Bayangan itu beralasan karena problem ini memiliki beberapa variabel yang memiliki
kesamaan dengan Knapsack problem. Kesamaan itu antara lain energi yang terbatas, adanya
masing-masing aktivitas yang memiliki nilai energi, dan pencarian jumlah maksimum/minimum
aktivitas.
Secara umum pemecahan problem Knapsack memanfaatkan array dua dimensi. Seperti problem
Knapsack di bawah ini beserta solusinya.
Tabel Soal Knapsack
Tabel Solusi Knapsack
Jika memperhatikan solusi Knapsack di gambar, solusi tersebut memanfaatkan array dua dimensi
dimana baris dan kolom merepresentasikan W=berat dan i=benda. Hasil maksimumnya adalah
value 13. Agar mencapai nilai maksimum 13 yang ada di pojok kanan bawah harus melakukan
pengisian sebanyak i*w.
Pemecahan menggunakan solusi Knapsack mulai dipertanyakan karena kami bingung
memodifikasi array tanpa harus melakukan scanning sebanyak i*w sementara di problem Basic
Routines jumlah aktivitas maksimum dan energi maksimum adalah 1 ≤ N ≤ 100,000 dan 1 ≤ E ≤
1,000,000. Berarti jika dibuat array dua dimensi NxE, program harus menscanning data sebanyak
105 x10
6 . Apabila itu dilakukan ada kemungkinan akan Time Limit Excedeed atau TLE. Selain
itu di dalam problem Basic Routine juga mempertimbangkan prioritas lexicographical apabila
aktivitas memiliki energi yang sama.
Maka kami beralih untuk mencari algoritma lain. Algoritma yang kami gunakan adalah
melakukan sorting berdasarkan prioritas. Maksudnya, untuk mengambil aktifitas mana saja yang
dapat dilakukan Ronny, diurutkan berdasar prioritas value dan lexicographical aktifitas.
Sehingga setelah terurut, Ronny dapat mengambil aktifitas dengan value energi terkecil hingga
mencapai energi maksimum yang dimiliki Ronny.
Algoritma
Untuk menyimpan data dua tipe data aktivitas(string) dan value(int) yang berbeda kami
memerlukan STL Pair.
String Int
Aktifitas Value
Lalu setiap Pair itu dikumpulkan dalam vector bernama data.
0
1
2
...
N-1
aktifitas aktifitas aktifitas aktifitas aktifitas
value
value
value
value
value
Hasil aktivitas yang dikerjakan Ronny akan disimpan dalam vector _hasilKegiatan.
Setelah beberapa kali coretan, kami akhirnya membuat Algoritma dari pemecahan problem Basic
Routines seperti berikut.
1. Masukkan data aktivitas dan value(energi)nya ke dalam Pair
2. Masukan Pair tersebut ke dalam Vector<Pair> data
3. Lakukan sort berdasarkan
a. Value dari aktivitas. Mulai dari value terkecil hingga terbesar.
b. Apabila value sama maka sort berdasar lexicographicalnya
4. Mulai dari i=0 hingga E energi.
a. Jika (Energi-data[i].second>=0)
i. Masukkan data[i].first ke _hasilKegiatan
ii. Energi=Energi-data[i].second+(Kegiatan ke i+1);
5. Cetak _hasilKegiatan
PseudoCode
1. Masukkan data aktivitas dan value energinya ke dalam Pair
...
//input
For i=0; i<N; i++
Input _namaKegiatan
Input _energi
_pasangan=make_pair(_namaKegiatan, _energi);
...
2. Masukkan Pair tersebut ke dalam Vector<Pair> data
data.push_back(_pasangan);
3. Sort
sort( data.begin, data.end, less_than_second);
/*
Fungsi Sort
*/
less_than_second( pair b1, pair b2 ){
if(b1.second < b2.second)return true; /*Jika energi aktivtias berbeda */
else if(b1.second==b2.second){ //Jika energi aktivitas sama
if(b1.first<b2.first)
return true;
else return false;
}
else return false;
}
Lakukan sort berdasarkan
a. Value dari aktivitas. Mulai dari value terkecil hingga terbesar.
b. Apabila value sama maka sort berdasar lexicographicalnya
4. Mengambil energi
...
For i=0; i<N; i++
if(Energi-data[i].second>=0){
hasilKegiatan.push_back(data[i].first); //Simpan ke _hasilKegiatan
jumlahKegiatan++;
Energi=Energi-data[i].second+jumlahKegiatan; //Kurangkan energinya
} else {
i=N;
}
...
Mulai dari i=0 hingga E energi.
Jika (Energi-data[i].second>=0) atau masih memiliki energi
i. Masukkan data[i].first ke _hasilKegiatan
ii. Energi=Energi-data[i].second+(Kegiatan ke i+1);
5. Cetak _hasilKegiatan
cetak(){
for i=0; i<jumlah; i++
cetak hasilKegiatan[i]
} Kompleksitas dari algoritma ini adalah O(E) yaitu sebanyak energi yang dimiliki oleh Ronny.
Buzz Trouble
Problem code: BUZZOFF
Analisis
Berdasarkan informasi dari rekan kami Ahmad Sodik, problem ini memperlihatkan pola
penjumlahan bilangan Fibonacci. Jadi hasil dari input problem ini akan menghasilkan output
seperti berikut
Input Fibonacci Output
0
1
2
3
4
5
6
1
1
2
3
5
8
13
-
1
1+ 2 = 3
1+2+3 = 6
1+2+3+5=11
1+2+3+5+8=19
1+2+3+5+8+13=32
Melihat output yang ditampilkan, sebenarnya kita bisa menggunakan dynamic problem. Karena
input ke n menghasilkan n ditambah akumulai n-1. Tapi kemungkinan akan Time Limit
Excedeed apabila data inputannya mencapai 1018
.
Kita dapat mencari bilangan Fibonacci ke-n dengan menggunakan formula Binet:
Untuk menjumlahkan bilangan Fibonacci hingga ke n
= fibonacci1+ fibonacci2+ fibonacci3 fibonacci4+ .... fibonaccin
=Fibonaccin+3 – 2
Jika dibuat implementasi dalam C++ kami membuat seperti berikut.
hasil=((pow(((1+sqrt(5))/2),N+3)-pow(((1-sqrt(5))/2),N+3))/sqrt(5))-2;
Setelah dicoba berkali-kali ternyata nilai pow akan menghasllkan bilangan desimal 0,00... yang
dapat menyebabkan hasil akhir tidak akurat. Oleh karena itu kita membuat satu fungsi pangkat
baru dengan pseudocode seperti di bawah ini.
double pows(a, b){
if(b == 0)
return 1LL;
buff=pows(a,b/2);
buff *=buff;
buff=fmod(buff,MOD);
if((b%2)==1){
buff *=a;
}
buff=fmod(buff,MOD);
return buff;
}
Pows ini akan bekerja dengan cara memecahnya menjadi dua bagian dan akan melakukan rekursi
pecah dua bagian lagi hingga pangkat terkecil. Contohnya, jika ada 1012
, fungsi ini akan
memecah menjadi 106 dan 10
6. 10
6 itu akan dipecah juga lagi menjadi 10
3 dan 10
3. Begitu
seterusnya. Setiap kali dipecah akan dikalikan nilainya. Sehingga akan diketahui berapa nilai
pangkatnya.
Sayangnya nilai pows kami juga tetap menghasilkan bilangan desimal. Kami memahami
problemnya bukan terletak pada pows tapi pada formula implementasi yang kami buat itu
sendiri. Akhirnya kami beralih untuk mencari formula cepat mencari bilangan fibonacci ke n lain
selain menggunakan Binet. Setelah melakukan pencarian akhirnya menemukan pemecahan fast
fibonacci menggunakan Matrix Exponentiation.
Fibonacci sendiri memiliki matrix identitas seperti di bawah ini.
Sekarang jika diletakkan angka fibonacci yang pertama ke matriks sebalah kanan dan akan dikali
hasilnya
Atau sama dengan juga
Cara cepat untuk melakukan perpangkatan adalah dengan algoritma di bawah ini
Array fib di bawah mewakili bilangan matriks fibonacci.
fib[2][2]= {{1,1},{1,0}},
ret[2][2]= {{1,0},{0,1}},
tmp[2][2]= {{0,0},{0,0}};
Kemudian dibuat fungsi Fibonacci dengan input n.
Selanjutnya dilakukan pengecekan apakah nilai n bilangan genap atau ganjil
Jika ia ganjil Lakukan dua kali pengisian matriks tmp seperti di bawah ini. Jika
genap cukup satu kali. Cara di bawah adalah mengalikan matriks ret dan fib.
Hasil matriks tmp dimodulos 10000000007
for(i=0; i<2; i++) for(j=0; j<2; j++) for(k=0; k<2; k++){
tmp[i][j]=(tmp[i][j]+ret[i][k]*fib[k][j]);
tmp[i][j]%=MOD;
}
for(i=0; i<2; i++) for(j=0; j<2; j++) ret[i][j]=tmp[i][j];
Nilai tmp akan menjadi nilai fibonacci, setelah itu n/2 artinya dikecilkan
pangkatnya
for(i=0; i<2; i++) for(j=0; j<2; j++) fib[i][j]=tmp[i][j];
n/=2;
Setelah menggunakan fast fibonacci itu kita mengetahui bahwa kita tidak memerlukan lagi
fungsi pows yang telah dibuat dan rumus pencarian jumlah fibonacci cukup seperti Fibonaccin+3
– 2. Kompleksitas dari fast fibonacci adalah O(log n).
SPOJ Problem Set (classical)
12558. Collision Issue
Problem code: CDC12_C
Solusi
Untuk mengetahui panjang sisi dari segitiga ABC kita dapat menghitungnya dengan rumus
Pythagoras. Misal untuk Test Case pertama (untuk input titik poin yang decimal harus dibulatkan
2 angka di belakang koma):
a (Xa, Ya) = (0, 0)
b (Xb, Yb) = (0, 3)
c (Xc, Yc) = (3, 0)
Kita umpamakan segitiga yang belum kita ketahui bentuknya seperti gambar di bawah :
Untuk mencari panjang titik a ke b adalah
C = = = 3
Untuk mencari panjang titik b ke c adalah
A = = =
Untuk mencari panjang titik a ke b adalah
B = = = 3
Dari rumus untuk mencari sudut yang terdapat di soal untuk mecari sudut C:
= C
= C2
= A2 + B
2 – C
2
= (A2 + B
2 – C
2 ) /
= (A2 + B
2 – C
2 ) /
sehingga :
cos(ø) = (A2 + B
2 – C
2 ) / (untuk Øc)
= (18 + 9 – 9 ) /
cos(ø) = (A2 + C
2 – B
2 ) / (untuk Øb)
= (18 + 9 – 9 ) /
cos(ø) = (B2 + C
2 – A
2 ) / (untuk Øa)
= (9 + 9 – 18 ) /
Karena kita ingin mencari sudutnya maka kita gunakan aturan arc cos. Untuk rumus di atas
adalah untuk mencari sudut c. Kita juga perlu membulatkan setiap sudut 2 angka di belakang
koma.
Øc = acos ( cos(ø) ) = 45◦
Øb = acos ( cos(ø) ) = 45◦
Øa = acos ( cos(ø) ) = 90◦
Sekarang kita sudah mengetahui besar sudut dan besar panjang dari segitiga di atas. Oleh karena
itu kita sudah dapat menentukan nama segitiga yang kita cari. Dikarenakan terdapat sisi yang
sama dan adanya sudut yang besarnya 90◦ maka nama segitiga adalah Isosceles Right Triangle
Pseudocode
A = sqrt( abs(x3-x2) * abs(x3-x2) + abs(y3-y2) * abs(y3-y2) );
B = sqrt( abs(x3-x1) * abs(x3-x1) + abs(y3-y1) * abs(y3-y1) );
C = sqrt( abs(x2-x1) * abs(x2-x1) + abs(y2-y1) * abs(y2-y1) );
/*Mencari cosinus dari setiap sudut berdasarkan rumus di atas*/
cosA = (B*B + C*C - A*A) / ( pow(8*B*B*B*C*C*C, 1.0/3.0) ));
cosB = (A*A + C*C - B*B) / ( pow(8*A*A*A*C*C*C, 1.0/3.0) ));
cosC = (A*A + B*B - C*C) / ( pow(8*A*A*A*B*B*B, 1.0/3.0) ));
/*Sudut dibulatkan dua angka di belakang koma*/
angleA = floor( (acos (cosA) * 180.0 / PI )*100 + 0.5)/100;
angleB = floor( (acos (cosB) * 180.0 / PI )*100 + 0.5)/100);
angleC = floor( (acos (cosC) * 180.0 / PI )*100 + 0.5)/100);
/*panjang sisi dibulatkan dua angka di belakang koma*/
A = floor(A*100 + 0.5) / 100;
B = floor(B*100 + 0.5) / 100;
C = floor(C*100 + 0.5) / 100;
if(A == B && A == C && B == C)
print "Scenario #%d: Equilateral Equiangular\n"
else if(A == B || A == C || B == C)
if(angleA == 90.00 || angleB == 90.00 || angleC == 90.00)
print "Scenario #%d: Isosceles Right Triangle\n"
else if(angleA > 90.00 || angleB > 90.00 || angleC > 90.00)
printf("Scenario #%d: Isosceles Obtuse\n", i);
else
print "Scenario #%d: Isosceles Acute\n"
else
if(angleA == 90.00 || angleB == 90.00 || angleC == 90.00) {
print "Scenario #%d: Scalene Right Triangle\n"
else if(angleA > 90.00 || angleB > 90.00 || angleC > 90.00) {
print "Scenario #%d: Scalene Obtuse\n"
else
print "Scenario #%d: Scalene Acute\n"
Karena dalam problem ini tidak menggunakan perulangan dalam solusinya maka
kompleksitasnya O(1)
SPOJ Problem Set (classical)
12559. Drastic Race
Problem code: CDC12_D
Solusi
Contoh untuk Test Case yang pertama
t = Waktu
K = Banyak kesempatan untuk menggunakan kecepatan boostnya
s = Jarak yang ditempuh saat waktu t
Ronny akan selalu menggunakan kemampuan Boostnya di saat dia masih memilikinya namun di
saat kemampuannya tersebut habis dia berada di dalam suatu kondisi untuk memilih apakah
harus berhenti terlebih dahulu untuk merecover kemampuan boostnya atau melanjutkan
perjalanannya dengan kecepatan normalnya. Kondisi tersebut dapat diselesaikan seperti berikut :
1. Ronny tidak akan melakukan recover apabila dengan kecepatan normalnya di detik
berikutnya ternyata dia telah sampai di finish.
2. Ronny tidak akan melakukan recover apabila kecepatan normalnya lebih dari kecepatan
boostnya. Sehingga lebih baik dia terus menggunakan kecepatan normalnya hingga garis
finish.
3. Ronny akan melakukan recover apabila dengan kecepatan normalnya di detik berikutnya
dia belum sampai di finish dan kecepatan normalnya kurang dari kecepatan Boostnya..
Pseudocode
Drasticrace(tRainbow, distance, vRonny, boost, chance, recover)
while(temp < distance) {
if(chance > 0)
distanceNow += vRonny + boost
ans = ans + 1
chance = chance - 1
else if(vRonny > boost)
distanceNow += vRonny;
ans = ans + 1
else
if(temp + vRonny >= m)
distanceNow += vRonny;
ans = ans + 1
else
chance = chance + recover
ans = ans + 1
if(ans < tRainbow)
print "Scenario #%d: Ronny wins in time %d\n"
else
print "Scenario #%d: Ronny will be annihilated\n"
Kompleksitas algoritma penyelesaian problem ini adalah
O(D / V)
Keterangan :
D = Jarak menuju Finish
V = Kecepatan regular Ronny
SPOJ Problem Set (classical)
12563. Halt The War
Problem code: CDC12_H
Solusi
Problem ini dapat diselesaikan dengan Segment Tree Range Sum. Dimana kita harus membentuk
sebuah Tree untuk menyimpan jumlah letter yang di bawa oleh Rainbowlandian. Terdapat dua
operasi fungsi pada tree yaitu untuk Update dan Query.
Pseudocode (Update dan Propagate)
propagate(node, L, R, x)
st[node] += (R-L+1)*x
prop[node] += x
return
update(node, L, R, i, j)
if (i<=L && R<=j){
propagate(node, L, R, 1)
return
mid = (L+R)>>1;
if (prop[node] > 0)
propagate(2*node, L, mid, prop[node])
propagate((2*node+1, mid+1, R, prop[node])
prop[node] = 0
if (mid>=i)
update(2*node, L, mid, i, j)
if (mid+1<=j)
update(2*node+1, mid+1, R, i, j)
st[node] = st[2*node] + st[2*node+1]
return
Keterangan
node = index array node
L = batas bawah
R = batas atas
I = Operasi update dimulai i
J = Operasi update sampai j
St[] = node tree untuk menyimpan value (dijelaskan di bawah)
Prop[] = node tree untuk penanda dan update (dijelaskan di bawah)
Untuk contoh kasus yang pertama kita dapat menggambarkan proses rekursinya sebagai berikut.
Modification 1 2. Karena index kita mulai dari 0 maka kita kurang i dan j dengan 1.
Rumus utama dari tree ini adalah induk dari setiap node st[] merupakan jumlah array st[] dari
anak – anaknya.
st[node] = st[2*node] + st[2*node+1]
Fungsi Propagate merupakan fungsi penanda bahwa induk dari node telah dilakukan update dan
juga untuk mengisi nilai dari array st[node] dengan nilai interval L sampai R. Misal kita akan
melakukan update dari interval 1 sampai dengan 4 kita tidak perlu langsung melakukan operasi
update sampai terhadap node anak – anaknya. Namun apabila operasi membutuhkan update
sampai anak – anaknya baru kita lakukan operasi update. Untuk lebih jelasnya kita coba Query
Modification 2 3.
Dari contoh di atas untuk operasi update(2, 0, 1, 1, 2) dikarenakan array prop[2] bernilai lebih
dari nol maka kita juga harus lakukan proses update untuk node anak dari array index 2 yaitu
array untuk index 4 dan 5.
Pseudocode (Query)
query(node, L, R, i, j)
if (I <= L && R <= j)
return st[node];
mid = (L+R) / 2;
if (prop[node] > 0)
propagate(2*node, L, mid, prop[node])
propagate(2*node+1, mid+1, R, prop[node])
prop[node] = 0
if (mid>=i)
ret += query(2*node, L, mid, i, j);
if (mid+1<=j)
ret += query(2*node+1, mid+1, R, i, j);
return ret
Untuk fungsi Query kita contohkan test case yang pertama. Answer 2, 2
Di dalam fungsi query juga terdapat fungsi propagate dikarenakan mungkin fungsi query akan
menampilkan jumlah interval hingga node tertentu yang belum terupdate oleh node induknya
atau nilai prop[node] induknya masih bernilai lebih dari 0.
Dikarenakan solusi dari problem ini menggunakan konsep tree maka kompleksitasnya O(N log
N)
SPOJ Problem Set (tutorial)
12561. Forbidden Machine
Problem code: CDC12_F
Dalam problem ini programmer membuat sebuah program untuk dimasukkan dalam
sebuah mesin, agar mesin dapat menunemukan jawaban yang sesesuai untuk guard.
Penjelasan:
N adalah no state dari machine.
M adalah no transisi (perpindahan) mesin.
I , J, C adalah perpindahan state dari i ke j yang berisi huruf C.
F adalah akhir state.
E adalah no yang menunjukkan final(akhir) state,
Q adalah awal state.
S adalah jumlah proses(test) yang dilakukan.
Input :
Output:
4 8 1 0
0 0 1 a 1 0 a
1 2 b 2 1 b
0 3 b 3 0 b 3 2 a
2 3 a 3
ababbaa abababab aaaabbbb
N, M, F, Q
I, J, C
Q
S
Scenario #1:
ababbaa Rejected
abababab Accepted
aaaabbbb Accepted
Penyelesaian(penjelasan algorithma) dengan input:
State(langkah) pada input dapat digambarkan sebagai berikut:
E adalah final state, maka akhir dari input char karakter S harus pada E.
E = 0, maka akhir harus pada state 0.
Q adalah awal state, maka awal langtkah dari input char harus pada state Q.
Q = 0, maka awal state harus pada state 0.
a b a b b a a
langkah :
1. 0 1 = a (benar, ada arah dari 0 ke 1).
2. 1 2 = b (benar, ada arah dari 1 ke 2).
3. 2 3 = a (benar, ada arah dari 2 ke 3).
4. 3 0 = b (benar, ada arah dari 3 ke 4).
5. 0 3 = b (benar, ada arah dari 0 ke 3).
6. 3 2 = a (benar, ada arah dari 3 ke 2).
7. 2 3 = a (benar, ada arah dari 2 ke 3).
Dari uji diatas akhir state tidak pada state ke-0, maka kasus tersebut tidak di terima oleh mesin(
output : Rejected ).
0 1
3 2
a
b b
a
a
a
b b
a b a b a b a b
langkah :
1. 0 1 = a (benar, ada arah dari 0 ke 1).
2. 1 0 = a (benar, ada arah dari 1 ke 0).
3. 0 1 = a (benar, ada arah dari 0 ke 1).
4. 1 0 = a (benar, ada arah dari 1 ke 0).
5. 0 3 = b (benar, ada arah dari 0 ke 3).
6. 3 0 = b (benar, ada arah dari 3 ke 0).
7. 0 3 = b (benar, ada arah dari 0 ke 3).
8. 3 0 = b (benar, ada arah dari 3 ke 0).
Dari uji diatas akhir state pada state ke-0, maka kasus tersebut di terima oleh mesin( Output :
Accepted ).
a a a a b b b b
langkah :
1. 0 1 = a (benar, ada arah dari 0 ke 1).
2. 1 2 = b (benar, ada arah dari 1 ke 2).
3. 2 3 = a (benar, ada arah dari 2 ke 3).
4. 3 0 = b (benar, ada arah dari 3 ke 4).
5. 0 1 = a (benar, ada arah dari 0 ke 1).
6. 1 2 = b (benar, ada arah dari 1 ke 2).
7. 2 3 = a (benar, ada arah dari 2 ke 3).
8. 3 0 = b (benar, ada arah dari 3 ke 4).
Dari uji diatas akhir state pada state ke-0, maka kasus tersebut di terima oleh mesin( Output :
Accepted ). Pseudo code: time = 0
for(k=0...<=jmlState)
{
if(DP[time][k])
for(l=0....<=jmlState)
if(array[k][l][charUji-'a'])
{
DP[time+1][l] = true
}
}
time++;
input char(charUji)
}
Kompleksitas : Perulangan 1 l dari 0 sampai jmlSatate Perulangan 2 k dari 0 sampai jmlSatate l=k Kompleksitas = O( l*l) = O(2^l)
SPOJ Problem Set (tutorial)
12564. Innovative Combination
Problem code: CDC12_I
Dalam problem ini, programmer membuat sebuah program untuk memecahkan sebuah
code pasword yang lupa kombinasinya.
Penjelasan:
T adalah banyak uji coba.
N adalah jumlah bilangan dalam sequence.
M adalah jumlah bilangan special.
Squence M adala rangkaian bilangan yang di masukkan.
Squence N dalah rangkaian bilangan special.
Input: Output:
Penyelesaian(penjelasan algorithma) dengan input:
Permasalahan special number dapat digambarkan dengan berapa sering bilangan special number
keluar dalam suatu rangkaian bilangan.
3
5 2
3 3 5 4 4
5 4
7 4
4 8 5 5 5 4 8
4 4 8 5
10 6
3 3 7 6 5 5 7 6 6 6
5 7 6 6 3 5
Scenario #1: 12
Scenario #2: 2223
Scenario #3: 224422
3 3 5 4 4
5 4 sehingga didapat , 5 ada 1 dan 4 ada 2, sehingga output 12
4 8 5 5 5 4 8
4 4 8 5 Sehingga di dapat, 4 ada 2, 4 ada 2, 8 ada 2 dan 5 ada 3, sehingga output 2223
3 3 7 6 5 5 7 6 6 6
5 7 6 6 3 5 Sehingga di dapat:
5 ada 2, 7 ada 2, 6 ada 4, 6 ada 4, 3 ada 2 dan 5 ada 2, sehingga ouput
224422
Sedangkan untuk menghitung banyak bilangan yang muncul adalah
for(i=1...<=N)
B[num]=+1
Keterangan:
Num = bilangan special
B[num] = list bilangan index spesial
Pseudocode
Innovative(Num, SN, N, M)
for i to N
b[Num] += 1
for i to M
print b[SN]
Keterangan:
Num = Special Number dalam sequence
SN = Special Number
N = panjang sequence
M = panjang Special Number
Komplesitas:
Perulangan 1 sampai N, sehingga kompleksitas O(n)