您的位置:首页 > 其它

查找和是某一值或者某一范围的的所有可能

2017-08-19 18:48 232 查看
昨天做笔试题,有这么一道题,稍有难度。

题目是:

输入包含多组数据。第一行为一个正整数T(T<=1000),表示测试数据的组数。然后是T组测试数据,每组测试数据占两行,第一行包/含两个整数n和m,表示ASCII码的范围。第二行为所使用的大写字

母的掩码,共26个数字构成的串,对应于26个大写字母,表示使用/对应字母的数量。输出对于每一组输入数据,输出一行"Case #k ans",

表示第k组数据的结果是ans。

样例输入

2

1 100

1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

100 200

1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

样例输出

Case #1: 3

Case #2: 4

Hint

说明:请注意严格按照格式进行输出,如 Case #1: 3(Case的C大写,冒号后有空格)第一组数据即A,B,C各一个的情况下,求ASCII和在1到100的组合,共有三组:即A(65),B(66),C(67);第二组在同等情况下求和在100到200范围内的组合,共四组,即AB(131),AC(132),BC

(133),ABC(198),其余交换字母位置的可能不考虑。

首先看一下第一种方法。用两个变量收缩走,但是这样无法讨论不连续的情况。

//没有考虑到不连续的情况
#define A 65
int Fun(vector<int> &ve,string &str,int i)
{
if(ve.size() < 1 || i < 0 || str.length() <= 0)
exit(1);
int small = ve[i*2];
int big = ve[i*2+1];

int start = 0;
int end = 0;
int max_cur = 0;
int max_i = 0;
while(end < str.length())
{
if(str[end] == '0')
{
end++;
continue;
}
max_cur += (end +++ A);
if(max_cur <= big && max_cur >= small)
{
max_i ++;
}
else if(max_cur < small)
continue;
else
{
max_cur -= (start +++ A);
}
}
max_cur -= (start +++ A);
while(max_cur <= big && max_cur >= small)
{
max_cur -= (start +++ A);
max_i ++;
}
return max_i;
}
int main()
{
int n;
vector<int> ve;
cin>>n;
string * str = new string
;
for(int i = 0; i < n; ++i)
{
int tmp;
cin>>tmp;
ve.push_back(tmp);
cin>>tmp;
ve.push_back(tmp);
cin>>str[i];
}
for(int i = 0; i < n; ++i)
{
int kn = Fun(ve,str[i],i);
cout<<"Case #"<<i+1<<": "<<kn<<endl;
}
return 0;
}这种情况有明显的缺点,但是我们可以有新情况,第二种情况是利用子集树来进行
代码如下:

#define A 65
void Fun(vector<int> &ve_tmp,int i,int len,int small,int big,int &num)
{
int sum = 0;
int k = 0;
while(i)
{
if(i & 1)
{
sum += ve_tmp[k];
}
k++;
i >>= 1;
}
if(sum >= small && sum <= big)
num++;
}
int Fun(vector<int> &ve,string &st,int i)
{
int small = ve[i * 2];
int big = ve[i * 2 + 1];
int num = 0;
vector<int> ve_tmp;
for(int i = 0; i < st.length(); ++i)
{
if(st[i] == '1')
{
ve_tmp.push_back(i + A);
}
}
int len = ve_tmp.size();
for(int i = 0; i < (1 << len); ++i)
{
Fun(ve_tmp,i,len,small,big,num);
}
return num;
}
int main()
{
int n;
vector<int> ve;
cin>>n;
string * str = new string
;
for(int i = 0; i < n; ++i)
{
int tmp;
cin>>tmp;
ve.push_back(tmp);
cin>>tmp;
ve.push_back(tmp);
cin>>str[i];
}
for(int i = 0; i < n; ++i)
{
int kn = Fun(ve,str[i],i);
cout<<"Case #"<<i+1<<": "<<kn<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐