Merhaba Arkadaşlar,
Bu haftaki sorum şu olacak, http://codeforces.com/contest/703/problem/B
Basitce anlatıcak olacaksam Maşka kardeşimiz şehir şehir dolaşan biri. Bu dolaştığı şehirlerden bazıları başkent.
Sehirler birbirine bağlı ve başkentler bütün şehirlere bağlı. Her şehrin bir güzellik değeri var bizden istenen toplam güzellik sayısını bulmamız.
Bir örnek aşağıda görülebilir :
- şehir 2'ye, 2. şehir 3'e , 3 şehir başkent olduğu için herkese 4 de 1 bağlı.
http://codeforces.com/predownloaded/17/1d/171ddc86762c931ed2d5f9f3b8ebed6d12503783.png
Bu resim şu datadan oluşuyor
4 1 ---> 4 şehir ve 1 tane başkent var
2 3 1 2 ---> Her şehir için güzellik sayısı
3 ----> 1 tane olan başkentin indexi
Benim çözümüm şu oldu , doğru çalışıyor fakat performansı yetersiz olduğundan kabul edilmedi.
Algoritmayı özetliyecek olursam :
1 - Bütün guzellikSayilari 'ni
toplamGuzellikSayisi += guzellikSayilari[i]*guzellikSayilari[i+1];
şeklinde geziyorum çünkü yanyana olan şehirlerin birbirne bağlı olması gerekior
2- Eğer i, başkent ise o zaman
guzellikSayilari[i]*guzellikSayilari[i+1]
yerine bütün diziyi bir daha dolaş ve hepsi ile çarp çünkü başkent herkese bağlı olması gerekiyor.
3- İkinci maddeyi yaparken
if ( k == i || k == i-1 || ( k < i && baskentIndexleri.canFind(k)))
continue;
Gibi bir kontrolle iki kere bağlamanın önüne geçtim.
int toplamGuzellikSayisi = 0;
void main() {
auto ilkSatir = stdin.readln.strip.split().map!(a => to!int(a));
auto toplamSehirSayisi = ilkSatir[0];
auto toplamBaskentSayisi = ilkSatir[1];
auto guzellikSayilari = stdin.readln.strip.split().map!(a => to!int(a));
auto baskentIndexleri = stdin.readln.strip.split().map!(a => to!int(a) - 1);
int enSonBaskentIndeksi = 0;
for ( int i = 0; i < guzellikSayilari.length; i++) // İkiser ikiser carpma yapamadim
{
if ( enSonBaskentIndeksi < toplamBaskentSayisi && i == baskentIndexleri[enSonBaskentIndeksi] )
{
enSonBaskentIndeksi++;
for ( int k = 0; k < guzellikSayilari.length; k++) // Filter yapilabilirdi
{
if ( k == i || k == i-1 || ( k < i && baskentIndexleri.canFind(k)))
continue;
toplamGuzellikSayisi += guzellikSayilari[i]*guzellikSayilari[k];
}
}
else if ( i < guzellikSayilari.length -1 )
toplamGuzellikSayisi += guzellikSayilari[i]*guzellikSayilari[i+1];
}
if ( baskentIndexleri[0] != 0 && baskentIndexleri[$-1] != toplamSehirSayisi-1)
toplamGuzellikSayisi += guzellikSayilari[0]*guzellikSayilari[$-1];
writeln(toplamGuzellikSayisi);
}
Dediğim gibi algoritma çalıştı ama performansı düşük çıktı ben aklımda daha iyi bir algoritma buldum O(N) ile çalışıcak sizde görebiliyormusunuz?
Şimdi geleyim yapmak isteyip yapamadıklarıma:
1 -
toplamGuzellikSayisi += guzellikSayilari[i]*guzellikSayilari[i+1];
işi for döngüsü yerine aralıklar ile nasıl yapardım.
Yani elimde 1 ,2 ,3 ,4 gibi bir dizi var for döngüsüz 12 + 23 + 34 + 41 nasıl yapabilirim?
2 - Diyelimki yine elimde 1'den 10 kadar bir dizi var ben 6. ve 8. indexleri atmak istiyorum.
Acaba doğru yöntem auto a = chain(dizi[0..6], dizi[7], dizi[8..$]) midir? Acaba biraz kötü durmuyormu?
Drop fonksiyonları gördüğüm kadarıyla sadece baştan atıyor.
Saygılarımla
Erdemdem
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]
Permalink
Reply