Задания
Версия для печати и копирования в MS Word
Тип 26 № 39255
i

Пред­при­я­тие про­из­во­дит за­куп­ку из­де­лий A и B, на ко­то­рую вы­де­ле­на опре­делённая сумма денег. У по­став­щи­ка есть в на­ли­чии раз­лич­ные мо­ди­фи­ка­ции этих из­де­лий по раз­лич­ной цене. При по­куп­ке не­об­хо­ди­мо ру­ко­вод­ство­вать­ся сле­ду­ю­щи­ми пра­ви­ла­ми.

1.  Нужно ку­пить как можно боль­ше из­де­лий, не­за­ви­си­мо от их типа и мо­ди­фи­ка­ции.

2.  Если можно раз­ны­ми спо­со­ба­ми ку­пить мак­си­маль­ное ко­ли­че­ство из­де­лий, нужно вы­брать тот спо­соб, при ко­то­ром будет куп­ле­но как можно боль­ше из­де­лий B.

3.  Если можно раз­ны­ми спо­со­ба­ми ку­пить мак­си­маль­ное ко­ли­че­ство из­де­лий с оди­на­ко­вым ко­ли­че­ством из­де­лий B, нужно вы­брать тот спо­соб, при ко­то­ром вся по­куп­ка будет де­шев­ле.

Опре­де­ли­те, сколь­ко всего будет куп­ле­но из­де­лий B и какая сумма оста­нет­ся не­ис­поль­зо­ван­ной.

Вход­ные дан­ные.

За­да­ние 26

Пер­вая стро­ка вход­но­го файла со­дер­жит два целых числа: N  — общее ко­ли­че­ство из­де­лий у по­став­щи­ка и M  — сумма вы­де­лен­ных на за­куп­ку денег (в руб­лях). Каж­дая из сле­ду­ю­щих N строк со­дер­жит целое число (цена из­де­лия в руб­лях) и сим­вол (ла­тин­ская буква A или B), опре­де­ля­ю­щий тип из­де­лия. Все дан­ные в стро­ках вход­но­го файла от­де­ле­ны одним про­бе­лом.

В от­ве­те за­пи­ши­те два целых числа: сна­ча­ла ко­ли­че­ство за­куп­лен­ных из­де­лий типа B, затем остав­шу­ю­ся не­ис­поль­зо­ван­ной сумму денег.

При­мер вход­но­го файла:

6 130

30 A

50 A

60 B

20 B

70 B

10 A

В дан­ном слу­чае можно ку­пить не более 4 из­де­лий, из них не более 2 из­де­лий B. Ми­ни­маль­ная цена такой по­куп­ки 120 руб­лей (по­ку­па­ем из­де­лия 30A, 60B, 20B, 10A). Оста­нет­ся 10 руб­лей. В от­ве­те надо за­пи­сать числа 2 и 10.

 

Ответ:

Спрятать решение

Ре­ше­ние.

Со­зда­дим два дву­мер­ных мас­си­ва. В пер­вый мас­сив счи­та­ем все эле­мен­ты из файла и от­сор­ти­ру­ем его по воз­рас­та­нию. После этого по­счи­та­ем мак­си­маль­ное ко­ли­че­ство из­де­лий, ко­то­рое можем за­ку­пить на за­дан­ную сумму, по­сле­до­ва­тель­но при­бав­ляя к пе­ре­мен­ной sum цену из­де­лия в те­ку­щем эле­мен­те. Далее в от­дель­ный дву­мер­ный мас­сив вы­не­сем толь­ко остав­ши­е­ся из­де­лия B. Далее будем пе­ре­би­рать уже взя­тые из­де­лия с конца, пы­та­ясь за­ме­нить из­де­лия A на из­де­лия B таким об­ра­зом, чтобы сумма взя­тых из­де­лий не пре­вы­ша­ла за­дан­ную сумму. После этого по­счи­та­ем, сколь­ко из­де­лий B по­лу­чи­лось за­ку­пить.

 

При­ведём ре­ше­ние на языке Pascal.

var

n, m, x, t1, t2, countB, count, i, j: integer;

z: string;

arrayAB: array [1..916, 1..2] of integer;

arrayB: array [1..916, 1..2] of integer;

sum: integer;

f: text;

begin

assign(f,'C:\26.txt');

reset(f);

readln(f, n, m);

countB := 0;

count := 0;

sum := 0;

for i := 1 to n do begin

if not eof(f) then

readln(f, x, z)

else break;

if z.Contains('A') then begin

arrayAB[i, 1] := x;

arrayAB[i, 2] := 0;

end;

if z.Contains('B') then begin

arrayAB[i, 1] := x;

arrayAB[i, 2] := 1;

end;

end;

for i := 1 to n-1 do

for j := i + 1 to n do

if arrayAB[i, 1] > arrayAB[j, 1] then begin

t1 := arrayAB[i, 1];

t2 := arrayAB[i, 2];

arrayAB[i, 1] := arrayAB[j, 1];

arrayAB[i, 2] := arrayAB[j, 2];

arrayAB[j, 1] := t1;

arrayAB[j, 2] := t2;

end;

for i := 1 to n do

if (sum + arrayAB[i, 1]) < m then begin

sum := sum + arrayAB[i, 1];

count := count + 1;

end

else break;

x := 1;

for i := count + 1 to n do

if arrayAB[i, 2] = 1 then begin

arrayB[x, 1] := arrayAB[i, 1];

arrayB[x, 2] := arrayAB[i, 2];

x := x + 1;

end;

x := 1;

for i := count downto 1 do begin

if arrayAB[i, 2] = 0 then begin

if ((sum - arrayAB[i, 1] + arrayB[x, 1]) > m) then break;

sum := sum - arrayAB[i, 1] + arrayB[x, 1];

arrayAB[i, 1] := arrayB[x, 1];

arrayAB[i, 2] := arrayB[x, 2];

x := x + 1;

end;

end;

for i := 1 to count do

if arrayAB[i, 2] = 1 then countB := countB + 1;

writeln(countB, ' ', m - sum);

end.

 

В ре­зуль­та­те ра­бо­ты дан­но­го ал­го­рит­ма при вводе дан­ных из файла в усло­вии по­лу­ча­ем ответ  — 154 87.

 

Ответ: 154 87.

 

При­ме­ча­ние. Путь к файлу не­об­хо­ди­мо ука­зать со­глас­но рас­по­ло­же­нию файла на Вашем ком­пью­те­ре.

 

При­ведём ре­ше­ние на языке Python.

f = open('26 (11).txt')

n, m = f.readline().split()

arrayAB = [[0] * 2 for i in range(916)]

arrayB = [[0] * 2 for i in range(916)]

n = int(n)

m = int(m)

count = 0

sumi = 0

for i in range(n):

x, z = f.readline().split()

arrayAB[i][0] = int(x)

if z == 'B':

arrayAB[i][1] = 0

if z == 'A':

arrayAB[i][1] = 1

arrayAB.sort()

i = 0

while m > arrayAB[i][0] + sumi:

if (sumi + arrayAB[i][0]) < m:

sumi = sumi + arrayAB[i][0]

count += 1

i += 1

x = 1

for i in range(count, n):

if arrayAB[i][1] == 0:

arrayB[x][0] = arrayAB[i][0]

arrayB[x][1] = arrayAB[i][1]

x += 1

x = 1

for i in range(count - 1, -1, -1):

if arrayAB[i][1] == 1:

if (sumi - arrayAB[i][0] + arrayB[x][0]) > m:

break

sumi = sumi - arrayAB[i][0] + arrayB[x][0]

arrayAB[i][0] = arrayB[x][0]

arrayAB[i][1] = arrayB[x][1]

x += 1

countB = 0

for i in range(count):

if arrayAB[i][1] == 0:

countB = countB + 1

print(countB, m - sumi)

 

При­ведём ре­ше­ние Алек­сандра Куз­не­цо­ва на языке Python.

f = open('26.txt')

n, m = [int(i) for i in (f.readline()).split()]

lA, lB= [], []

l=[]

for i in f:

p, t = [str(j) for j in i.split()]

p=int(p)

l.extend([(p, t)])

f.close()

sumi=0

l.sort()

k=0

for p, t in l:

if sumi+p <= m:

if t=='A': lA.append(p)

if t=='B': k+=1

sumi+=p

elif t=='B' and sumi+p>m and len(lB)<=len(lA):

lB.append(p)

lA.sort()

lA=lA[::-1]

lB.sort()

for i in lB:

for j in range(len(lA)):

if sumi-lA[j]+i<=m:

sumi=sumi-lA[j]+i

k+=1

lA.pop(j)

break

print(k, m-sumi)


Аналоги к заданию № 38960: 39255 Все

Раздел кодификатора ФИПИ: