// Input: STAMPS{TYPES 0}\nCUSTOMERS{NUMS 0}\n
// Output: CUTSOMER_NUM (TYPE_NUM):{ TYPES | tie} | ---- none
// max_type_num == 4,fewest TYPE_NUM best, the with highest single-value best
// Method:
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <memory.h>
// STRUCTS
struct SSTAMPS
{
int types[100];
int num;
};
struct SCUSTOMERS
{
int totals[100];
int num;
};
struct SOUTPUT
{
int total;
int types[100];
int typeIndices[100];
int num;
int tie;
int typeNum;
};
// VARS
SOUTPUT tempOutput;
int buf[100];
int bufIndices[100];
// FUNCS
// read infos(stamps and customers)
bool readInfos(SSTAMPS *stamps, SCUSTOMERS *customers)
{
// reset
stamps->num = 0;
customers->num = 0;
// read stamps
while (scanf("%d", &stamps->types[stamps->num]) != EOF)
{
if (!stamps->types[stamps->num])
break;
stamps->num ++;
}
if (!stamps->num)
return false;
// read customers
while (scanf("%d", &customers->totals[customers->num]) != EOF)
{
if (!customers->totals[customers->num])
break;
customers->num ++;
}
return true;
}
// check outputs
void checkOutputs(SOUTPUT *cur, SOUTPUT *temp, int *types, int num)
{
// count type num
temp->typeNum = 0;
int i, j;
memset(buf, 0, sizeof(int) * temp->num);
for (i = 0; i < temp->num-1; ++i)
{
if (buf[i] == 1)
continue;
temp->typeNum ++;
for (j = i+1; j < temp->num; ++j)
{
if (temp->typeIndices[i] == temp->typeIndices[j])
{
buf[j] = 1;
}
}
}
if (!buf[i])
temp->typeNum ++;
// compare
bool better = false;
// more type num OR OR
if (temp->typeNum > cur->typeNum)
{
better = true;
}
// less stamp num
else if (temp->typeNum == cur->typeNum && temp->num < cur->num)
{
better = true;
}
// bigger max one
else if (temp->typeNum == cur->typeNum && temp->num == cur->num && temp->types[0] > cur->types[0])
{
better = true;
}
// tie
else if (temp->typeNum == cur->typeNum && temp->num == cur->num && temp->types[0] == cur->types[0])
{
for (i = 0; i < temp->num; ++i)
{
buf[i] = temp->types[i];
bufIndices[i] = temp->typeIndices[i];
}
// sort
for (i = 0; i < temp->num-1; ++i)
{
for (j = i+1; j < temp->num; ++j)
{
if (buf[j] > buf[i])
{
int data = buf[j];
buf[j] = buf[i];
buf[i] = data;
data = bufIndices[j];
bufIndices[j] = bufIndices[i];
bufIndices[i] = data;
}
else if (buf[j] == buf[i] && bufIndices[j] < bufIndices[i])
{
int data = bufIndices[j];
bufIndices[j] = bufIndices[i];
bufIndices[i] = data;
}
}
}
// check equal cur
bool equalCur = true;
for (i = 0; i < temp->num; ++i)
{
if (bufIndices[i] != cur->typeIndices[i])
{
equalCur = false;
break;
}
}
if (equalCur)
return;
cur->tie = 1;
}
// if better copy temp to cur
if (better)
{
cur->tie = 0;
cur->num = temp->num;
cur->typeNum = temp->typeNum;
for (int i = 0; i < temp->num; ++i)
{
cur->types[i] = temp->types[i];
cur->typeIndices[i] = temp->typeIndices[i];
}
}
}
// get best division,
int getBestDivision(SOUTPUT *output, int curRet, int *types, int num, int total)
{
// end condition
if (curRet > 4 || total < 0 || (curRet == 4 && total))
return 0;
if (!total)
{
tempOutput.num = curRet;
return 1;
}
// go through types from bigger one to smaller one
for (int i = 0; i < num; ++i)
{
tempOutput.types[curRet] = types[i];
tempOutput.typeIndices[curRet] = i;
if (getBestDivision(output, curRet+1, types, num, total - types[i]))
{
checkOutputs(output, &tempOutput, types, num);
}
}
return 0;
}
// divide customers' total, output the list
void divide(SOUTPUT *output, SSTAMPS *stamps, int total)
{
output->total = total;
// reset
output->num = 0;
output->tie = 0;
output->typeNum = 0;
// sort
int i, j;
for (i = 0; i < stamps->num-1; ++i)
{
for (j = i+1; j < stamps->num; ++j)
{
if (stamps->types[j] > stamps->types[i])
{
int temp = stamps->types[i];
stamps->types[i] = stamps->types[j];
stamps->types[j] = temp;
}
}
}
// reset temp output
tempOutput.num = 0;
tempOutput.tie = 0;
tempOutput.typeNum = 0;
// get division
getBestDivision(output, 0, stamps->types, stamps->num, total);
}
// output
void outputLine(SOUTPUT *output)
{
if (output->num > 0)
{
printf("%d (%d):", output->total, output->typeNum);
// normal
if (!output->tie)
{
for (int i = output->num-1; i >= 0; --i)
{
printf(" %d", output->types[i]);
}
printf("\n");
}
// tie
else
{
printf(" tie\n");
}
}
// none
else if (!output->num)
{
printf("%d ---- none\n", output->total);
}
}
// solve
void solve(SSTAMPS *stamps, SCUSTOMERS *customers)
{
SOUTPUT output;
for (int i = 0; i < customers->num; ++i)
{
divide(&output, stamps, customers->totals[i]);
outputLine(&output);
}
}
#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
SSTAMPS stamps;
SCUSTOMERS customers;
while (readInfos(&stamps, &customers))
{
solve(&stamps, &customers);
}
return 0;
}
POJ-1010-STAMPS
最新推荐文章于 2021-12-07 08:45:11 发布