您的位置:首页 > 其它

蓝桥杯练习系统心得

2015-03-07 15:13 155 查看
1.问题描述Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。输入格式输入包含一个整数n。输出格式输出一行,包含一个整数,表示Fn除以10007的余数。说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。样例输入10样例输出55样例输入22样例输出7704数据规模与约定1 <= n <= 1,000,000。答案:#include <stdlib.h>
#include <stdio.h> 
#define MOD 10007
#define MAXN 1000001
int n, i, F[MAXN];
int main()
{
scanf("%d", &n);
F[1] = 1;
F[2] = 1;
for (i = 3; i <= n; ++i)
F[i] = (F[i-1] + F[i-2]) % MOD;
printf("%d\n", F
);
return 0;
}
2问题描述  给定n个十六进制正整数,输出它们对应的八进制数。输入格式  输入的第一行为一个正整数n (1<=n<=10)。  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。输出格式  输出n行,每行为输入对应的八进制正整数。注意  输入的十六进制数不会有前导0,比如012A。  输出的八进制数也不能有前导0。样例输入239123ABC样例输出714435274提示  先将十六进制数转换成某进制数,再由某进制数转换成八进制。错误答案:
#include<iostream>
using namespace std;
#include <algorithm>
#include <string>
#include <math.h>
//#include<vector>

int main()
{
<span style="white-space:pre">	</span>//vector<int> x;
<span style="white-space:pre">	</span>int a[10][100];
<span style="white-space:pre">	</span>int k = 0;
<span style="white-space:pre">	</span>string s;
<span style="white-space:pre">	</span>int n;
<span style="white-space:pre">	</span>int sum=0;
<span style="white-space:pre">	</span>cin >> n;
<span style="white-space:pre">	</span>while (k<n)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>cin >> s;
<span style="white-space:pre">		</span>for (int i = 0; i < s.length(); i++)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>if (s[i] >= '0'&&s[i] <= '9')
<span style="white-space:pre">			</span>{
<span style="white-space:pre">				</span>sum += (s[i] - '0')*pow(16, s.length()-1- i);
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>else
<span style="white-space:pre">			</span>{
<span style="white-space:pre">				</span>sum += (s[i] - 'A' + 10)*pow(16, s.length() -1 - i);
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>//cout << sum<<endl;
<span style="white-space:pre">		</span>int j = 1;
<span style="white-space:pre">		</span>while (sum!=0)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>a[k][j] = sum % 8;
<span style="white-space:pre">			</span>sum = sum / 8;
<span style="white-space:pre">			</span>j++;
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>a[k][0] = j-1;
<span style="white-space:pre">		</span>k++;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>for (int j = 0; j < k; j++)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>for (int i = a[j][0]; i >0; i--)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>cout << a[j][i];
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>cout << endl;
<span style="white-space:pre">	</span>}

<span style="white-space:pre">	</span>return 0;
}
正确答案:
// 十六进制转换8进制 AC

#include <iostream>
#include <string>
using namespace std;
int arr[10000001];

int main()
{
int n,len_str,i,j;
string str,str2;
cin>>n;
while(n--)
{
cin>>str;
len_str=str.length();
str2="";

// 十六进制转换为二进制
for(i=0;i<len_str;++i)
{
switch(str[i])
{
case '0':str2+="0000";break;
case '1':str2+="0001";break;
case '2':str2+="0010";break;
case '3':str2+="0011";break;
case '4':str2+="0100";break;
case '5':str2+="0101";break;
case '6':str2+="0110";break;
case '7':str2+="0111";break;
case '8':str2+="1000";break;
case '9':str2+="1001";break;
case 'A':str2+="1010";break;
case 'B':str2+="1011";break;
case 'C':str2+="1100";break;
case 'D':str2+="1101";break;
case 'E':str2+="1110";break;
case 'F':str2+="1111";break;
default:break;
}
}

// 修正位数
if(len_str%3==1)	str2="00"+str2;

else if(len_str%3==2)	str2="0"+str2;

len_str=str2.length();
// 二进制转换八进制
j=0;
for(i=0;i<=len_str-2;i+=3)
{
arr[j]=(str2[i]-'0')*4+(str2[i+1]-'0')*2+(str2[i+2]-'0');
++j;
}

for(i=0;i<j;++i)
{
if(i==0 && arr[i]==0)	continue;
cout<<arr[i];
}
cout<<endl;

}
return 0;
}
3.问题描述  123321是一个非常特殊的数,它从左边读和从右边读是一样的。  输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。输入格式  输入一行,包含一个正整数n。输出格式  按从小到大的顺序输出满足条件的整数,每个整数占一行。样例输入52样例输出899998989989998899数据规模和约定  1<=n<=54。答案:
#include<iostream>
using namespace std;
//#include <algorithm>
#include <string>
#include <math.h>
//#include<vector>

int main()
{
int n;
int a[6];
cin>>n;
for(int i=10001;i<=99999;++i)
{
a[4]=i/10000;
a[3]=(i/1000)%10;
a[2]=(i/100)%10;
a[1]=(i/10)%10;
a[0]=i%10;
if(a[0]==a[4]&&a[1]==a[3]&&a[0]+a[1]+a[2]+a[3]+a[4]==n)
{
cout<<i<<endl;
}
}
for(int i=100001;i<=999999;++i)
{
a[5]=i/100000;
a[4]=(i/10000)%10;
a[3]=(i/1000)%10;
a[2]=(i/100)%10;
a[1]=(i/10)%10;
a[0]=i%10;
if(a[0]==a[5]&&a[1]==a[4]&&a[2]==a[3]&&a[0]+a[1]+a[2]+a[3]+a[4]+a[5]==n)
{
cout<<i<<endl;
}
}
return 0;
}
心得:蓝桥杯多用暴力破解法4问题描述利用字母可以组成一些美丽的图形,下面给出了一个例子:ABCDEFGBABCDEFCBABCDEDCBABCDEDCBABC这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。输入格式输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。输出格式输出n行,每个m个字符,为你的图形。样例输入5 7样例输出ABCDEFGBABCDEFCBABCDEDCBABCDEDCBABC数据规模与约定1 <= n, m <= 26。AC
#include<iostream>
using namespace std;
#include<algorithm>
#include<list>
#include<string>

void show(list<char> l,int m)
{
list<char>::iterator itr = l.begin();
int i = 0;
while (itr != l.end()&&i<m)
{
cout << *itr;
itr++;
i++;
}
cout << endl;
}

int main()
{
string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
list<char> l;
int n, m;
cin >> n >> m;
l.assign(s.begin(), s.begin() + m);

show(l,m);
for (int i = 1; i < n; i++)
{
l.push_front('A' + i);
show(l,m);
}
return 0;
}
心得:STL模板的应用以及对规律的观察5问题描述给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。输入格式第一行包含一个数n,表示序列长度。第二行包含n个正整数,表示给定的序列。第三个包含一个正整数m,表示询问个数。接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。输出格式总共输出m行,每行一个数,表示询问的答案。样例输入51 2 3 4 521 5 22 3 2样例输出42数据规模与约定对于30%的数据,n,m<=100;对于100%的数据,n,m<=1000;保证k<=(r-l+1),序列中的数<=106。
#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
//#include<list>
//#include<string>

int main()
{
vector <int> v;
int n,b;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> b;
v.push_back(b);
}
int x;
cin >> x;
while (x--)
{
int begin,end,a;
cin >> begin >> end >> a;
vector<int> copy;
copy.assign(v.begin()+begin-1, v.begin()+end);
sort(copy.begin(), copy.end());
reverse(copy.begin(), copy.end());
cout << copy.at(a - 1);
}
return 0;
}
心得:依旧是STL的应用,另外end不用+1的原因是end不包括在copy中6问题描述如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数。求L位K进制数中K好数的数目。例如K = 4,L = 2的时候,所有K好数为11、13、20、22、30、31、33 共7个。由于这个数目很大,请你输出它对1000000007取模后的值。输入格式输入包含两个正整数,K和L。输出格式输出一个整数,表示答案对1000000007取模后的值。样例输入4 2样例输出7数据规模与约定对于30%的数据,KL <= 106;对于50%的数据,K <= 16, L <= 10;对于100%的数据,1 <= K,L <= 100。AC
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define mod 1000000007
__int64 dp[105][105];

int main()
{
int k,l,i,j,x;
scanf("%d%d",&k,&l);
for(i = 0; i<k; i++)
dp[1][i] = 1;
for(i = 2; i<=l; i++)
for(j = 0; j<k; j++)
for(x = 0; x<k; x++)
if(x!=j-1&&x!=j+1)//根据题意,本位的数字与前面的数字是不能相邻的
{
dp[i][j]+=dp[i-1][x];
dp[i][j]%=mod;
}
__int64 sum = 0;
for(i = 1; i<k; i++)
{
sum+=dp[l][i];
sum%=mod;
}
printf("%I64d\n",sum%mod);

return 0;
}
心得:i是几个数,j是最后一个数,动态规划要想好数组,找好边界7问题描述有一棵 n 个节点的树,树上每个节点都有一个正整数权值。如果一个点被选择了,那么在树上和它相邻的点都不能被选择。求选出的点的权值和最大是多少?输入格式第一行包含一个整数 n 。接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值。接下来一共 n-1 行,每行描述树上的一条边。输出格式输出一个整数,代表选出的点的权值和的最大值。样例输入51 2 3 4 51 21 32 42 5样例输出12样例说明选择3、4、5号点,权值和为 3+4+5 = 12 。数据规模与约定对于20%的数据, n <= 20。对于50%的数据, n <= 1000。对于100%的数据, n <= 100000。权值均为不超过1000的正整数。AC:查看网址http://www.tuicool.com/articles/3eimue
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <algorithm>

#define M 100100 //最大长度

using namespace std;

typedef struct Node

{

int vex;

Node* next;

}Child;

Child* head[M];//链表头数组

int f[M][2], power[M], visit[M];

//pow[]权值数组,p[i]表示第i个节点的权值
//f[i][1]保留节点i时最大权值,f[i][0]不保留节点i时的最大权值
//visit[i]==1表示i点被访问过,visit[i]==0表示节点i未被访问过

//添加边(对称的)
void addADJ(int u, int v)

{

Child *p, *q;

p = (Child*)malloc(sizeof(Child));

p->vex = v;

p->next = head[u];

head[u] = p;

q = (Child*)malloc(sizeof(Child));

q->vex = u;

q->next = head[v];

head[v] = q;

}

//动态规划获取结果

void GetResul(int v)

{

visit[v] = 1;

Child *p;

for (p = head[v]; p != NULL; p = p->next)

{

if (visit[p->vex] == 0)

{

GetResul(p->vex);

f[v][1] = f[v][1] + f[p->vex][0];

f[v][0] += max(f[p->vex][0], f[p->vex][1]);

}

}

f[v][1] += power[v];

}

int main()

{

int i, j, u, v, n;

memset(head, NULL, sizeof(head));

memset(f, 0, sizeof(f));

memset(visit, 0, sizeof(visit));

scanf("%d", &n);

for (i = 1; i <= n; i++)

{

scanf("%d", &power[i]);

}

for (i = 1; i<n; i++)

{

scanf("%d%d", &u, &v);

addADJ(u, v);

}

GetResul(1);//从节点1开始进行动态规划

printf("%d\n", max(f[1][0], f[1][1]));//结果输出

return 0;

}
心得:注意头插法,还有动态规划的思想,注意数组值常常为答案。8问题描述给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。输入格式第一行两个整数n, m。接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。输出格式共n-1行,第i行表示1号点到i+1号点的最短路。样例输入3 31 2 -12 3 -13 1 2样例输出-1-2数据规模与约定对于10%的数据,n = 2,m = 2。对于30%的数据,n <= 5,m <= 10。对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。参考网址http://blog.csdn.net/libin56842/article/details/19910545
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;

const int inf = 1<<30;
const int L = 200000;

struct Edges
{
    int x,y,w,next;
} e[L<<2];

int head[L];
int dis[L];
int vis[L];
int cnt[L];

void AddEdge(int x,int y,int w,int k)
{
    e[k].x = x,e[k].y = y,e[k].w = w,e[k].next = head[x],head[x] = k;
}
int relax(int u,int v,int c)
{
    if(dis[v]>dis[u]+c)
    {
        dis[v] = dis[u]+c;
        return 1;
    }
    return 0;
}

int SPFA(int src)
{
    int i;
    memset(cnt,0,sizeof(cnt));
    dis[src] = 0;
    queue<int> Q;
    Q.push(src);
    vis[src] = 1;
    cnt[src]++;
    while(!Q.empty())
    {
        int u,v;
        u = Q.front();
        Q.pop();
        vis[u] = 0;
        for(i = head[u]; i!=-1; i=e[i].next)
        {
            v = e[i].y;
            if(relax(u,v,e[i].w)==1 && !vis[v])
            {
                Q.push(v);
                vis[v] = 1;
            }
        }
    }
}

int main()
{
    int t,n,m;
    int i,j;
    scanf("%d%d",&n,&m);
    memset(e,-1,sizeof(e));
    for(i = 1; i<=n; i++)
    {
        dis[i] = inf;
        vis[i] = 0;
        head[i] = -1;
    }
    for(i = 0; i<m; i++)
    {
        int x,y,w;
        scanf("%d%d%d",&x,&y,&w);
        AddEdge(x,y,w,i);
    }
    SPFA(1);
    for(i = 2; i<=n; i++)
        printf("%d\n",dis[i]);

    return 0;
}
心得:和上题非常类似,注意头插法,以及SPFA的模板。9问题描述  生成n个∈[a,b]的随机整数,输出它们的和为x的概率。输入格式  一行输入四个整数依次为n,a,b,x,用空格分隔。输出格式  输出一行包含一个小数位和为x的概率,小数点后保留四位小数样例输入2 1 3 4样例输出0.3333数据规模和约定  对于50%的数据,n≤5.  对于100%的数据,n≤100,b≤100.AC:
#include<iostream>
#include<cstdio>
using namespace std;
double dp[101][10001];
bool f[101][10001];
int n, a, b, xx;

double dfs(int i, int j)
{
if (f[i][j]) return dp[i][j];
f[i][j] = true;
if (i == 0)
if (j == 0)
return dp[i][j] = 1;
else return dp[i][j] = 0;

for (int q = b; q >= a; q--)
if (j - q >= 0)
dp[i][j] += dfs(i - 1, j - q);
dp[i][j] /= double(b - a + 1);
return dp[i][j];

}
int main()
{
scanf("%d%d%d%d", &n, &a, &b, &xx);

printf("%.4lf", dfs(n, xx));
return 0;
}
10问题描述Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路。道路被用来连接N个牧场,牧场被连续地编号为1到N。每一个牧场都是一个奶牛的家。FJ计划除去P条道路中尽可能多的道路,但是还要保持牧场之间 的连通性。你首先要决定那些道路是需要保留的N-1条道路。第j条双向道路连接了牧场Sj和Ej(1<= Sj <= N; 1 <= Ej <=N; Sj != Ej),而且走完它需要Lj的时间。没有两个牧场是被一条以上的道路所连接。奶牛们非常伤心,因为她们的交通系统被削减了。你需要到每一个奶牛的住处去安慰她们。每次你到达第i个牧场的时候(即使你已经到过),你必须花去Ci的时间和奶牛交谈。你每个晚上都会在同一个牧场(这是供你选择的)过夜,直到奶牛们都从悲伤中缓过神来。在早上起来和晚上回去睡觉的时候,你都需要和在你睡觉的牧场的奶牛交谈一次。这样你才能完成你的 交谈任务。假设Farmer John采纳了你的建议,请计算出使所有奶牛都被安慰的最少时间。输入格式第1行包含两个整数N和P。接下来N行,每行包含一个整数Ci。接下来P行,每行包含三个整数Sj, Ej和Lj。输出格式输出一个整数, 所需要的总时间(包含和在你所在的牧场的奶牛的两次谈话时间)。样例输入5 71010206301 2 52 3 52 4 123 4 172 5 153 5 6样例输出176数据规模与约定5 <= N <= 10000,N-1 <= P <= 100000,0 <= Lj <= 1000,1 <= Ci <=1,000。
#include<iostream>
#include<algorithm>
using namespace std;

int p[100005];

int c[10005];

struct edge
{
int u;
int v;
int w;

bool operator<(const edge &a)  const
{
return  c[u]+c[v]+2*w<c[a.u]+c[a.v]+2*a.w;

}
};

edge e[100005];

int n,esize;

void init()
{
for(int i=0;i<n;i++)
p[i]=i;

}
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);

}

int kruskal()
{

int ans=0;
for(int i=0;i<esize;i++)
{
int x=find(e[i].u);
int y=find(e[i].v);

if(x!=y)
{
ans+=2*e[i].w+c[e[i].u]+c[e[i].v];
p[x]=y;
}

}

return ans;
}

int main()
{

int p;
cin>>n>>p;

esize=p;

init();

int min_c=1000000000;
for(int i=0;i<n;i++)
{
cin>>c[i];
if(c[i]<min_c)  min_c=c[i];
}
int u,v,w;

for(int i=0;i<p;i++)
{
cin>>u>>v>>w;
e[i].u=u-1;
e[i].v=v-1;
e[i].w=w;
}

sort(e,e+esize);

int ans=kruskal();

ans+=min_c;

cout<<ans<<endl;

}
心得:kruskal算法的使用以及并合集的使用。11问题描述  任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001。  将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=2^7+2^3+2^0  现在约定幂次用括号来表示,即a^b表示为a(b)  此时,137可表示为:2(7)+2(3)+2(0)  进一步:7=2^2+2+2^0 (2^1用2表示)  3=2+2^0  所以最后137可表示为:2(2(2)+2+2(0))+2(2+2(0))+2(0)  又如:1315=2^10+2^8+2^5+2+1  所以1315最后可表示为:  2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)输入格式  正整数(1<=n<=20000)输出格式  符合约定的n的0,2表示(在表示中不能有空格)样例输入137样例输出2(2(2)+2+2(0))+2(2+2(0))+2(0)样例输入1315样例输出2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)提示用递归实现会比较简单,可以一边递归一边输出
#include<stdio.h>
int main()
{
int n;
void cimi(int n);
while(scanf("%d",&n)!=EOF)
{
cimi(n);
printf("\n");
}
return 0;
}
void cimi(int n)
{
int num;
int i,j,k;
int a[32];//数组定义为局部变量
num=0;
i=0;
while(n)
{
j=n%2;
if(j==1)
a[num++]=i;//存储第几次是1
i++;
n/=2;
}
for(i=num-1;i>=0;i--)
{
if(a[i]==0)
printf("2(0)");
else if(a[i]==1)
printf("2");
else if(a[i]==2)
printf("2(2)");
else if(a[i]>2)
{
printf("2(");
cimi(a[i]);
printf(")");
}
if(i!=0)
printf("+");//如果不是最后一个就得输出 +
}
}
12问题描述  给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的。输入格式  第一行一个数字L。  第二行是字符串S。  L大于0,且不超过S的长度。输出格式  一行,题目要求的字符串。  输入样例1:  4  bbaabbaaaaa  输出样例1:  bbaa  输入样例2:  2  bbaabbaaaaa  输出样例2:  aa数据规模和约定  n<=60  S中所有字符都是小写英文字母。  提示  枚举所有可能的子串,统计出现次数,找出符合条件的那个AC:
#include<string>
#include<iostream>
using namespace std;

int main()
{
int l,sum=0,flag=-1;
cin >> l;
string s;
cin >> s;
string temp,res;
for (int i = 0; i < s.length()-3; i++)
{
sum = 0;
temp=s.substr(i,l);
for (int j = 0; j < s.length()-3; j++)
{
if (temp==s.substr(j,l))
{
sum++;
}
}
if (sum>flag)
{
flag = sum;
res = temp;
}
}
cout << res;
return 0;
}
心得:主要还是对系统函数(字符串函数)的应用13从键盘读入n个整数放入数组中,编写函数CompactIntegers,删除数组中所有值为0的元素,其后元素向数组首端移动。注意,CompactIntegers函数需要接受数组及其元素个数作为参数,函数返回值应为删除操作执行后数组的新元素个数。输出删除后数组中元素的个数并依次输出数组元素。  样例输入: (输入格式说明:5为输入数据的个数,3 4 0 0 2 是以空格隔开的5个整数)  5  3 4 0 0 2  样例输出:(输出格式说明:3为非零数据的个数,3 4 2 是以空格隔开的3个非零整数)  3  3 4 2样例输入70 0 7 0 0 9 0样例输出27 9样例输入30 0 0
样例输出0AC:
include<string>#include<iostream>using namespace std;int CompactIntegers(int *p, int n){int num=n;int i = 0;while (i<num){if (p[i]==0){for (int j = i; j < num-1; j++){p[j] = p[j + 1];}num--;i = -1;}i++;}return num;}int main(){int n;cin >> n;int *p = new int;for (int i = 0; i <n; i++){cin >> p[i];}int num = CompactIntegers(p,n);cout << num << endl;for (int i = 0; i < num; i++){cout << p[i] << " ";}}
心得:搞不清楚的话多在纸上写一写14问题描述  对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢?输入格式  第一行一个数表示数据组数  每组输入数据共2行:  第1行给出总共的数字的个数n和要取的数的个数m,1<=n<=m<=15,  第2行依次给出这n个数,其中每个数字的范围满足:a[i]的绝对值小于等于4。输出格式  每组数据输出1行,为最大的乘积。样例输入15 51 2 3 4 2样例输出48说明:这道题目一直通不过,用的是回溯法,不过自己认为还是有一定的参考价值。特别将它贴出来.,对于挑选问题,回溯法还是有优势的
#include<iostream>#include <string.h>using namespace std;int x[16];int a, b,m,amax;void fun(int k,int sum){if (k > a){if (m == b){if (sum>amax){amax = sum;return;}}return;}if (m<b){sum *= x[k-1];m++;fun(k + 1,sum);sum /= x[k-1];m--;}fun(k + 1, sum);}int main(){int n;cin >> n;while (n--){memset(x,0,sizeof(x));int sum;m = 0,amax=0,sum=1;cin >> a>> b;for (int i = 0; i < a;i++){cin >> x[i];}fun(1,sum);cout << amax;}return 0;}
以上便是寒假所看的有一些蓝桥杯的题目
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: