蓝桥杯练习系统心得

时间:2021-02-11 16:46:03
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[n]); return 0; }


2

问题描述   给定n个十六进制正整数,输出它们对应的八进制数。 输入格式   输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式   输出n行,每行为输入对应的八进制正整数。 注意   输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。
样例输入 2
39
123ABC
样例输出 71
4435274
提示   先将十六进制数转换成某进制数,再由某进制数转换成八进制。



错误答案:

#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 样例输出 899998
989989
998899
数据规模和约定   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 问题描述

利用字母可以组成一些美丽的图形,下面给出了一个例子:

ABCDEFG

BABCDEF

CBABCDE

DCBABCD

EDCBABC

这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。

输入格式输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。输出格式输出n行,每个m个字符,为你的图形。样例输入5 7样例输出ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
数据规模与约定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行,每行一个数,表示询问的答案。样例输入5
1 2 3 4 5
2
1 5 2
2 3 2
样例输出4
2
数据规模与约定

对于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 行,每行描述树上的一条边。

输出格式输出一个整数,代表选出的点的权值和的最大值。样例输入5
1 2 3 4 5
1 2
1 3
2 4
2 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 3
1 2 -1
2 3 -1
3 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 7
10
10
20
6
30
1 2 5
2 3 5
2 4 12
3 4 17
2 5 15
3 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
样例输入7
0 0 7 0 0 9 0
样例输出2
7 9
样例输入3
0 0 0

样例输出0
AC:

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[n];
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行,为最大的乘积。 样例输入 1
5 5
1 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;
}


以上便是寒假所看的有一些蓝桥杯的题目