soyoja님의 요청도 있고, lewha0 님이 안써주셔서 대신 씁니다.
[문제 해설]
인형의 개수가 많기 때문에 문제에 나온대로 시뮬레이션하다가는 답이 언제 나올지는 아무도 모릅니다.
잠시 생각해보면 나눠줄 인형의 개수를 m이라 할 때 (가장 적은 개수의 인형 수)를 한번에 나눠줄 지 판단할 수 있습니다.
이를 이용해서 인형의 개수로 소트한 후에 앞에서부터 보면서 d[i] * (n-i) <= m (d[i]: i번 인형의 개수. 소트한 상태, n은 인형 가지수, i는 0-based index) 이라면 d[i]개를 나눠줄 수 있다는 것을 한번에 계산할 수 있습니다.
또한 d[i] * (n - i) >m 이라면 모두에게게 d[i]개만큼 나눠줄 수 없다는 것이 되며 이 때에는 나머지 인형들은 최소 몇개를 나눠줄 수 있는지와 그 후에 남는 인형들을 계산하면 됩니다. 계산 식은 어렵지 않으니 생략합니다.
여기에서 신경 쓰셔야 되는 것은 소트를 하기 때문에 입력된 순서가 섞인다는 점입니다. 이는 원래 입력된 index를 같이 가지고 소트하는 것을 통해 해결할 수 있습니다.
[spoiler="소스코드 보기"]
~~~ cpp
#include
#include
#include
using namespace std;
int T, n, m;
struct Doll
{
int n, idx;
bool operator < (const Doll& rhs) const
{
if (n == rhs.n) return idx < rhs.idx;
return n < rhs.n;
}
};
int res[100000];
Doll d[100000];
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &m);
fill(res, res + n, -1);
for (int i = 0; i < n; ++i)
{
d[i].idx = i;
scanf("%d", &d[i].n);
}
sort(d, d + n);
int remain, adds = 0;
for (int i = 0; i < n; ++i)
{
int x = (d[i].n) * (n - i);
if (x <= m)
{
res[d[i].idx] = d[i].n;
m -= d[i].n;
}
else
{
remain = m / (n - i);
adds = m - (remain * (n - i));
break;
}
}
if (res[0] == -1)
printf("%d", remain + (adds-- > 0));
else
printf("%d", res[0]);
for (int i = 1; i < n; ++i)
{
if (res[i] == -1)
printf(" %d", remain + (adds-- > 0));
else
printf(" %d", res[i]);
}
printf("\n");
}
}
[/spoiler]
<div>[이 글은 과거 홈페이지에서 이전된 글입니다. <a href="http://algospot.andromeda-express.com/zbxe/editorial/50203">원문보기</a>]</div>
Toivoa
soyoja님의 요청도 있고, lewha0 님이 안써주셔서 대신 씁니다.
[문제 해설]
인형의 개수가 많기 때문에 문제에 나온대로 시뮬레이션하다가는 답이 언제 나올지는 아무도 모릅니다.
잠시 생각해보면 나눠줄 인형의 개수를 m이라 할 때 (가장 적은 개수의 인형 수)를 한번에 나눠줄 지 판단할 수 있습니다.
이를 이용해서 인형의 개수로 소트한 후에 앞에서부터 보면서 d[i] * (n-i) <= m (d[i]: i번 인형의 개수. 소트한 상태, n은 인형 가지수, i는 0-based index) 이라면 d[i]개를 나눠줄 수 있다는 것을 한번에 계산할 수 있습니다.
또한 d[i] * (n - i) >m 이라면 모두에게게 d[i]개만큼 나눠줄 수 없다는 것이 되며 이 때에는 나머지 인형들은 최소 몇개를 나눠줄 수 있는지와 그 후에 남는 인형들을 계산하면 됩니다. 계산 식은 어렵지 않으니 생략합니다.
여기에서 신경 쓰셔야 되는 것은 소트를 하기 때문에 입력된 순서가 섞인다는 점입니다. 이는 원래 입력된 index를 같이 가지고 소트하는 것을 통해 해결할 수 있습니다.
[spoiler="소스코드 보기"]
~~~ cpp
#include
#include
#include
using namespace std;
int T, n, m;
struct Doll
{
int n, idx;
bool operator < (const Doll& rhs) const
{
if (n == rhs.n) return idx < rhs.idx;
return n < rhs.n;
}
};
int res[100000];
Doll d[100000];
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &m);
fill(res, res + n, -1);
for (int i = 0; i < n; ++i)
{
d[i].idx = i;
scanf("%d", &d[i].n);
}
sort(d, d + n);
int remain, adds = 0;
for (int i = 0; i < n; ++i)
{
int x = (d[i].n) * (n - i);
if (x <= m)
{
res[d[i].idx] = d[i].n;
m -= d[i].n;
}
else
{
remain = m / (n - i);
adds = m - (remain * (n - i));
break;
}
}
if (res[0] == -1)
printf("%d", remain + (adds-- > 0));
else
printf("%d", res[0]);
for (int i = 1; i < n; ++i)
{
if (res[i] == -1)
printf(" %d", remain + (adds-- > 0));
else
printf(" %d", res[i]);
}
printf("\n");
}
}
17년 전