Problem Description
Jack最近喜欢到学校餐厅吃饭,好吃干净还便宜。 在学校餐厅,有a种汤,b种饭,c种面条,d种荤菜,e种素菜。 为了保证膳食搭配,Jack每顿饭都会点1~2样荤菜,1~2样素菜(不重复)。同时,在Jack心情好的时候,会点一样饭,再配上一种汤。在心情不好的时候,就只吃一种面条。 因为经济有限,Jack每次点餐的总价在min~max之间。Jack想知道,总共有多少种不同的点餐方案。
Input
输入数据第一行包含一个整数T,表示测试数据的组数,对于每组测试数据: 第一行为整数a,b,c,d,e(a,b,c,d,e>0 且 10>=a,b,c,d,e) 第二行为a个大于零的整数,表示a种汤的价格 第三行为b个大于零的整数,表示b种饭的价格 第四行为c个大于零的整数,表示c种面条的价格 第五行为d个大于零的整数,表示d种荤菜的价格 第六行为e个大于零的整数,表示e种素菜的价格 第七行为两个整数min max,表示每次点餐的价格范围
Output
对于每组测试数据,输出一行,包含一个整数,表示点餐方案数。
Sample Input
1
2 2 2 2 2
2 3
3 1
5 2
1 4
3 6
5 8
Sample Output
3
用到了了以前自己写的快排
/*Sample code to read in test cases:*/
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
template<class T>
int Partition(T A[],int p, int r)
{
T x = A[r];
int i = p-1;
for(int j=p;j<=r-1;j++)
{
if(A[j]<= x)
{
++i;
swap(A[i],A[j]);
}
}
swap(A[r],A[i+1]);
return i+1;
}
template<class T>
void QuickSort(T A[],int p, int r)
{
if(p<r)
{
int q = Partition(A,p,r);
QuickSort(A,p,q-1);
QuickSort(A,q+1,r);
}
}
void m_GetLine(fstream& file, istringstream& line)//将有效文件行读入字符流
{
string lineBuffer;
line.clear();
while (!file.eof() && lineBuffer.length() == 0)
getline(file, lineBuffer);
line.str(lineBuffer);
}
void Initialization(fstream& file, int menu[],int p, int r)//菜单价格初始化
{
istringstream line;
m_GetLine(file, line);
for (int i = p;i < r;++i)
line >> menu[i];
}
int main()
{
int a, b, c, d, e, n, cnt, min, max;
fstream file;
char sysInputFile[] = "{sysFileUrl}";
file.open(sysInputFile);
istringstream line;
m_GetLine(file, line);
line >> n;//数据组数
while (n-- != 0)
{
m_GetLine(file, line);
line >> a >> b >> c >> d >> e;
int *Soup = new int[a];
int *Rise = new int[b];
int *Nuddle = new int[c];
int *Meet = new int[d+1];
int *Vegetable = new int[e+1];
//初始化菜单价格,因为可能点到两份荤与两份素,添加价格为0的一种荤和一种素
//每次选两份,这样当选到价格为0的荤或素时可视为只点了一份荤或素
Meet[0] = 0;
Vegetable[0] = 0;
Initialization(file, Soup, 0, a);
Initialization(file, Rise, 0, b);
Initialization(file, Nuddle, 0, c);
Initialization(file, Meet, 1, d+1);
Initialization(file, Vegetable, 1, e+1);
//为减少循环次数,对价格进行排序,当前使用快排
QuickSort(Soup, 0, a-1);
QuickSort(Rise, 0, b-1);
QuickSort(Nuddle, 0, c-1);
QuickSort(Meet, 0, d);
QuickSort(Vegetable, 0, e);
m_GetLine(file, line);
line >> min >> max;
cnt = 0;//解决方案数清0
//使用回朔法(大概),通过price与max的判断去掉不必要的循环
//例如,加上某样菜价后超过max,则由排序过的价格可知不必再进行后续判断
for (int i = 1;i < d+1;++i)//荤
{
int price = Meet[i];
if (price > max)//针对各种可能的菜单
break;
for (int j = 1;j < e+1; ++j)//素,为了增加剪枝效率,先嵌套一次素和荤
{
price += Vegetable[j];
if (price > max)
{
price -= Vegetable[j];
break;
}
for (int h = 0;h < i;++h)//第二种荤
{
price += Meet[h];
if (price > max)
{
price -= Meet[h];
break;
}
for (int k = 0;k < j;++k)//第二种素
{
price += Vegetable[k];
if (price > max)
{
price -= Vegetable[k];
break;
}
for (int m = 0;m < c;++m)//面条
{
price += Nuddle[m];
if (price > max)
{
price -= Nuddle[m];
break;
}
else if (price < min)
{
price -= Nuddle[m];
continue;
}
else
{
price -= Nuddle[m];
++cnt;
}
}
for (int m = 0;m < b;++m)//米饭
{
price += Rise[m];
if (price > max)
{
price -= Rise[m];
break;
}
for (int x = 0;x < a;++x)//汤
{
price += Soup[x];
if (price > max)
{
price -= Soup[x];
break;
}
else if (price < min)
{
price -= Soup[x];
continue;
}
else
{
price -= Soup[x];
++cnt;
}
}
}
}
}
}
}
//do something
cout << cnt << endl;
delete []Soup;
delete []Rise;
delete []Nuddle;
delete []Meet;
delete []Vegetable;
}
return 0;
}