164 lines
3.6 KiB
C
164 lines
3.6 KiB
C
#include "flatten.h"
|
|
|
|
short a[MAX_LENGTH]; /* holds data */
|
|
long v[MAX_LENGTH]; /* holds no of presses */
|
|
short M; /* no. of buckets */
|
|
short N; /* height */
|
|
short nze; /* number of non-zero entries */
|
|
short step = 0; /* holds no. of steps so far */
|
|
short ent[MAX_PATH];
|
|
long nofp[MAX_PATH];
|
|
short nfp; /* bool : nothing can be fully *
|
|
* pressed */
|
|
|
|
void get_input()
|
|
{
|
|
register short i;
|
|
long total = 0;
|
|
FILE *ifp;
|
|
ifp = f_fopen("FLAT.INP", "r");
|
|
fscanf(ifp,"%hd\n", &M);
|
|
for (i = 1; i <= M; i++) { fscanf(ifp,"%hd", &a[i]); total += a[i]; }
|
|
N = total / M;
|
|
fclose(ifp);
|
|
}
|
|
|
|
void press_info()
|
|
{
|
|
long min = 0;
|
|
register short i;
|
|
if ((N - a[1]) > 0) { /* ana hesaplamalar */
|
|
v[2] = N - a[1];
|
|
v[1] = 0;
|
|
}
|
|
else {
|
|
v[1] = a[1] - N;
|
|
v[2] = 0;
|
|
}
|
|
for (i = 2; i < M; i++) {
|
|
v[i+1] = N - a[i] - v[i-1] + (2 * v[i]) ;
|
|
if (v[i+1] < min) min = v[i+1];
|
|
}
|
|
if (min < 0) /* eksi degerlerden kurtarmak icin */
|
|
for (i = 1 ; i <= M; i++) v[i] -= min;
|
|
for (i = 2; i <= M-1; i++) v[i] *= 2; /* uygun hale getirmek icin */
|
|
for (i = 1; i <= M; i++) if (v[i]) nze++;
|
|
}
|
|
|
|
void write_it(short e, long n)
|
|
{
|
|
ent[++step] = e;
|
|
nofp[step] = n;
|
|
}
|
|
|
|
short MPC(short e) /* maximum pressable chip */
|
|
{
|
|
if ((e == 1) || (e == M)) return a[e];
|
|
return (a[e] % 2) ? a[e] - 1 : a[e];
|
|
}
|
|
|
|
short eval(short e)
|
|
{
|
|
if (e == 1) return ((5 * a[1]) / 3);
|
|
else if (e == M) return ((5 * a[M]) / 3);
|
|
else return MPC(e);
|
|
}
|
|
|
|
short eval2(short e)
|
|
{
|
|
if (e == 1) return ( v[2] ? 4 * a[1] : a[1] );
|
|
else if (e == M) return ( v[M-1] ? 4 * a[M] : a[M] );
|
|
else {
|
|
short carpan = 0;
|
|
carpan += ( v[e-1] ? 1 :0 );
|
|
carpan += ( v[e+1] ? 1 :0 );
|
|
return (MPC(e) * (2 + carpan) / 2);
|
|
}
|
|
}
|
|
|
|
short find_2nd() /* assumes no pile can be fully pressed */
|
|
{
|
|
register short i;
|
|
short max = 0, ent = 0;
|
|
if ((a[1] && v[1]) && (((a[1] + a[2]) > v[2]) && v[2])) { ent = 1; max = a[1];}
|
|
for (i = 2; i < M ; i++)
|
|
if (a[i] && v[i])
|
|
if (((((MPC(i) / 2) + a[i - 1]) >= v[i - 1]) && v[i - 1]) || \
|
|
((((MPC(i) / 2) + a[i + 1]) >= v[i + 1]) && v[i + 1]))
|
|
if (MPC(i) > max) {ent = i; max = MPC(i); }
|
|
if ((a[M] && v[M]) && (((a[M] + a[M - 1]) > v[M - 1]) && v[M - 1]))
|
|
if (a[M] > max) return M;
|
|
return ent;
|
|
}
|
|
|
|
|
|
void flatten()
|
|
{
|
|
register short i;
|
|
short value, entry, no_chip, temp;
|
|
FILE *sol;
|
|
while (nze > 0) {
|
|
value = 0;
|
|
nfp = 0;
|
|
for (i = 1; i <= M; i++) {
|
|
if (a[i] && v[i]) {
|
|
if (a[i] >= v[i]) { /* hepsine basilabileni sec */
|
|
entry = i;
|
|
no_chip = v[i];
|
|
--nze;
|
|
nfp = 1;
|
|
break;
|
|
}
|
|
if (eval(i) > value) { /* eger fazla basilabilecek varsa */
|
|
value = eval(i);
|
|
entry = i;
|
|
no_chip = MPC(i);
|
|
}
|
|
if (eval(i) == value)
|
|
if (eval2(i) > eval2(entry)) {
|
|
entry = i;
|
|
no_chip = MPC(i);
|
|
}
|
|
}
|
|
}
|
|
if (!nfp)
|
|
if ((temp = find_2nd())) {
|
|
entry = temp;
|
|
no_chip = MPC(entry);
|
|
}
|
|
v[entry] -= no_chip;
|
|
a[entry] -= no_chip;
|
|
if (entry == M) { a[entry - 1] += no_chip; write_it(entry,no_chip);}
|
|
else if (entry == 1) { a[2] += no_chip; write_it(entry,no_chip);}
|
|
else {
|
|
a[entry - 1] += (no_chip / 2);
|
|
a[entry + 1] += (no_chip / 2);
|
|
write_it(entry,no_chip / 2);
|
|
}
|
|
}
|
|
sol = f_fopen("SOLUTION.TXT","w");
|
|
fprintf(sol,"%hd\n", step);
|
|
printf("%hd\n", step);
|
|
fclose(sol);
|
|
}
|
|
|
|
void putitout()
|
|
{
|
|
short i;
|
|
FILE *ofp;
|
|
ofp = f_fopen("FLAT.OUT","w");
|
|
fprintf(ofp,"%hd\n", step);
|
|
for (i = 1; i <= step; i++)
|
|
fprintf(ofp,"%hd %ld\n", ent[i], nofp[i]);
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
get_input();
|
|
press_info();
|
|
flatten();
|
|
putitout();
|
|
return 0;
|
|
}
|