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

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

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

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

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

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

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

За­да­ние 26

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

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

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

6 130

30 B

50 B

60 A

20 A

70 A

10 B

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

 

Ответ:

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

Ре­ше­ние.

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

 

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

var

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

z: string;

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

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

sum: integer;

f: text;

begin

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

reset(f);

readln(f, n, m);

countA := 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] = 0 then begin

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

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

x := x + 1;

end;

x := 1;

for i := count downto 1 do begin

if arrayAB[i, 2] = 1 then begin

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

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

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

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

x := x + 1;

end;

end;

for i := 1 to count do

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

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

end.

 

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

 

Ответ: 157 267.

 

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

 

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

f = open('26.txt')

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

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

arrayA = [[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 == 'A':

arrayAB[i][1] = 0

if z == 'B':

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:

arrayA[x][0] = arrayAB[i][0]

arrayA[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] + arrayA[x][0]) > m:

break

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

arrayAB[i][0] = arrayA[x][0]

arrayAB[i][1] = arrayA[x][1]

x += 1

countA = 0

for i in range(count):

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

countA = countA + 1

print(countA, m - sumi)

 

При­ведём ре­ше­ние Ильи Па­щу­ка (Ли­пецк) на языке Python.

f = open('26.txt') # счи­ты­ва­ние вход­ных дан­ных

maxsum = int(f.readline().replace('\n','').split(' ')[1])

l = f.readlines()

f.close()

 

ll = []

for i in l:

ii = i.replace('\n','').split(' ')

ii[0] = int(ii[0])

ll.append(ii)

 

# создаём от­дель­ные мас­си­вы для из­де­лий a и b, и сор­ти­ру­ем все 3 мас­си­ва

alist = [k[0] for k in ll if k[1] == 'A']

blist = [k[0] for k in ll if k[1] == 'B']

 

alist.sort()

blist.sort()

ll.sort(key=lambda k: k[0])

 

# счи­та­ем мак­си­маль­ное ко­ли­че­ство из­де­лий

msum = 0

maxc = 0

 

for i in ll:

if msum + i[0] <= maxsum:

msum += i[0]

maxc += 1

else: break

 

# "за­ку­па­ем" мак­си­маль­ное ко­ли­че­ство из­де­лий A

ba = []

 

for i in alist:

if len(ba) >= maxc: break

if sum(ba) + i <= maxsum:

ba.append(i)

else: break

 

# до­ку­па­ем из­де­лия B, при не­об­хо­ди­мо­сти уда­ляя из­де­лия A, пока не доберём до мак­си­маль­но­го зна­че­ния

bb = []

 

for i in blist:

if len(ba) + len(bb) >= maxc: break

if sum(ba) + sum(bb) + i <= maxsum:

bb.append(i)

else:

while sum(ba) + sum(bb) + i > maxsum: del ba[-1]

bb.append(i)

 

# вывод от­ве­та

print(len(ba))

print(maxsum - (sum(ba) + sum(bb)))

 

При­ведём ре­ше­ние Вя­че­сла­ва Ладын­ско­го на языке Python.

f = open('26.txt')

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

f = [i.split() for i in f]

f = sorted([[int(i[0]), i[1]] for i in f])

a = []

b = []

for i in range(len(f)):

if sum(a+b) + f[i][0] <= m:

if f[i][1] == 'A':

a.append(f[i][0])

f[i] = []

elif f[i][1] == 'B':

b.append(f[i][0])

f[i] = []

f = [i for i in f if i != []]

for i in f:

if i[1] == 'A':

if sum(a+b) - b[-1] + i[0] <= m:

a.append(i[0])

b.pop(-1)

print(len(a), m - sum(a + b))

 

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

f=open('26.txt')

n,s=map(int, f.readline().split())

a=sorted([[int(s.split()[0]),s.split()[1]] for s in f],key=lambda x: x[0],reverse=True)

packa,packb=[],[]

while s >= a[-1][0]:

x=a.pop()

(packa if x[1]=='A' else packb).append(x)

s-=x[0]

aa=[x for x in a if x[1]=='A']

while aa and packb and aa[-1][0]-packb[-1][0] <= s:

s-=aa[-1][0]-packb[-1][0]

packb.pop()

packa.append(aa.pop())

print(len(packa),s)


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

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