sairate c9f8710d03 sairate<sairate@sina.cn>
Signed-off-by: sairate <sairate@sina.cn>
2025-07-12 16:05:52 +08:00

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;
}