蓝桥杯练习系统心得

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.youkuaiyun.com/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;
}


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值