您的位置:首页 > 理论基础 > 数据结构算法

蓝桥杯练习系统试题持续更新

2016-12-30 23:17 225 查看
使用的IDE为Devc++5.4.0

入门训练
设置精度并且固定小数点的位数
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
int main()
{
int radius;
cin>>radius;
double p=atan(1.0)*4;
double area=p*radius*radius;
cout<<fixed<<setprecision(7)<<area<<endl;
return 0;
}


setprecision设置精度,前面加入fixed控制小数点的精度

斐波那契数列
时间限制1.0s内内存限制256MB

#include<iostream>
#include<vector>
using namespace std;

int main()
{
int n;
cin>>n;
int F
;
F[0]=0;
F[1]=F[2]=1;
if(n>=3)
{
for(int i=3;i<=n;i++)
{
F[i]=(F[i-1]+F[i-2])%10007;
}
}

cout<<F
<<endl;
return 0;
}

技巧:
          <1>将使用数组来保存F序列,只保存除10007的余数。
          <2>先令F[1]=1, F[2]=1,然后用F[i]=(F[i-1]+F[i-2])%10007来计算F[i]。

基础练习
闰年判断
       描述:能被4但不能被100或者400整除的数据
#include<iostream>
#include<vector>
using namespace std;

int main()
{
int n;
cin>>n;
if(n<1990||n>2050)
cout<<"no"<<endl;
if(n%4==0&&n%100!=0)cout<<"yes"<<endl;
else if(n%400==0)cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}


对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:

00000

00001

00010

00011

00100

请按从小到大的顺序输出这32种01串。

首先这个题如果暴力手动输入也是可以的,关键在于只有32次,那么要是7-8位该如何操作呢?

int main()
{
for(int i=0;i<=31;i++)//总共执行的次数为32次
{
int a[5]={0};//设置状态将5个位全部设置为00000
int num=i;//num记录当前执行的次数
int z=0;
while(num!=0)
{
a[z]=num%2;
z++;
num/=2;
}
for(int j=4;j>=0;j--)
cout<<a[j];
cout<<endl;
}
return 0;
}


基础练习 数列特征  

时间限制:1.0s   内存限制:256.0MB

问题描述

给出n个数,找出这n个数的最大值,最小值,和。

输入格式

第一行为整数n,表示数的个数。

第二行有n个数,为给定的n个数,每个数的绝对值都小于10000。

输出格式
输出三行,每行一个整数。第一行表示这些数中的最大值,第二行表示这些数中的最小值,第三行表示这些数的和。

#include<iostream>
using namespace std;
int main()
{
int num;
cin>>num;
int F[num];
long sum=0;
for(int i=1;i<=num;i++)
{
cin>>F[i-1];
sum=sum+F[i-1];
}
int min=F[0],max=F[0];
for(int i=1;i<=num;i++)
{
if(F[i-1]>max) max=F[i-1];
if(F[i-1]<min) min=F[i-1];
}
cout<<max<<endl;
cout<<min<<endl;
cout<<sum<<endl;
return 0;
}

  编译时间0.91s  第二个for循环中比较次数为2n次

基础练习 查找整数
时间限制:1.0s   内存限制:256.0MB
问题描述

给出一个包含n个整数的数列,问整数a在数列中的第一次出现是第几个。

输入格式

第一行包含一个整数n。

第二行包含n个非负整数,为给定的数列,数列中的每个数都不大于10000。

第三行包含一个整数a,为待查找的数。

输出格式
如果a在数列中出现了,输出它第一次出现的位置(位置从1开始编号),否则输出-1。
样例输入
6

1 9 4 8 3 9

9

样例输出
2
数据规模与约定
1 <= n <= 1000。

#include<iostream>
using namespace std;
int main()
{
int num;
cin>>num;
int F[num];
for(int i=1;i<=num;i++)
{
cin>>F[i-1];
}
int find;
cin>>find;
int x;
for(int i=1;i<=num;i++)
{
if(F[i-1]==find)
{x=i;break;
}
else x=-1;

}
cout<<x<<endl;

return 0;
}

注意:本次问题中必须加入break 不加break程序的时间会有很大的差别,不加break程序需要遍历到最后一个元素,如果数据量过大时,就会长期占用cpu 
详情见http://blog.csdn.net/luoweifu/article/details/16369007  这位大神关于break语句的详细说明

数字的求模取余,利用数组,定义与数字最大位数长度,然后利用每个数字存储在不同的数组序号之中解决

#include<iostream>
using namespace std;
int a[6];
int temp = 0;
int palindrome(int n)//n为判断是否为回文数
{
int i = 0,j,k;
while (n >= 1)
{
a[i++] = n % 10;
n = n / 10;
}
k = i - 1;
j = 0;
while (j < k)
{
if (a[j++] != a[k--])
return 0;
}
for (i = 0; i < 6; i++)
{
temp = temp + a[i];
}
return 1;
}
int main()
{
int n;
cin >> n;
int count = 0;
for (int i = 10000; i < 1000000; i++)
{
temp = 0;
if (palindrome(i) == 1 && temp == n)
{
cout << i << endl;
count++;
}
}
if (count == 0)
cout << "-1" << endl;
//cout << "sum=" << count << endl;
return 0;
}


//祥  3瑞  2生  辉   2三  2羊  献  气
#include<iostream>
using namespace std;
int main()
{
int a[8];

for(a[0]=1;a[0]<=9;a[0]++)
{
for(a[1]=0;a[1]<=9;a[1]++)
{
if(a[0]!=a[1])
for(a[2]=0;a[2]<=9;a[2]++)
{
if(a[2]!=a[0]&&a[2]!=a[1])
for(a[3]=0;a[3]<=9;a[3]++)
{
if(a[3]!=a[2]&&a[3]!=a[1]&&a[3]!=a[0])
for(a[4]=1;a[4]<=9;a[4]++)
{
if(a[4]!=a[3]&&a[4]!=a[2]&&a[4]!=a[1]&&a[4]!=a[0])
for(a[5]=0;a[5]<=9;a[5]++)
{
if(a[5]!=a[4]&&a[5]!=a[3]&&a[5]!=a[2]&&a[5]!=a[1]&&a[5]!=a[0])
for(a[6]=0;a[6]<=9;a[6]++)
{
if(a[6]!=a[5]&&a[6]!=a[4]&&a[6]!=a[3]&&a[6]!=a[2]&&a[6]!=a[1]&&a[6]!=a[0])
for(a[7]=0;a[7]<=9;a[7]++)
{
if(a[7]!=a[6]&&a[7]!=a[5]&&a[7]!=a[4]&&a[7]!=a[3]&&a[7]!=a[2]&&a[7]!=a[1]&&a[7]!=a[0])
{
int s=a[0]*1000+a[1]*100+a[2]*10+a[3];//上数
int x=a[4]*1000+a[5]*100+a[6]*10+a[1];
int sum=a[4]*10000+a[5]*1000+a[2]*100+a[1]*10+a[7];
if(sum==s+x)
{
cout<<a[4]<<a[5]<<a[6]<<a[1]<<endl;
}
}
}

}
}
}
}
}
}
}
return 0;
}


算法训练   区间k大数查询

问题描述

给定一个序列,每次询问序列中第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;
int find(int p[], int l, int r, int k)//从第l个数字开始 到第r个数字 ,第k大的数字
{
int m = r - l + 1;//需要储存 r-l+1个数字
int *newbase = new int[m];//新的数组存储查询的数字
int i, newc = 0;//newc为newbase计数器
for (i = l - 1; i<r; i++)//i从下标为第l-1个数字开始到下标为r-1个数组
{
newbase[newc++] = p[i];//拷贝复制  共m个
}
//重新排序  从大到小降序 选择排序
int tmp,index,j;//临时存储的中介机构
for (i = 0; i<m ; i++)
{
index =i;
for (j = i + 1; j < m; j++)
{
if (newbase[index] < newbase[j])
index = j;
}
//交换
{
tmp = newbase[index];
newbase[index] = newbase[i];
newbase[i] = tmp;
}

}

return newbase[k-1];//返回查询到的数额
}
int main()
{
int n;//定义序列长度
cin >> n;
int *p = new int
;//创建长度为n的序列
for (int i = 0; i<n; i++)//依次赋值
{
cin >> p[i];
}
//find(p, 1, 5, 2);
int m;//m为询问次数
cin >> m;
int count = 0;//查询次数计数器
int *q = new int[m];//创建m个单元存储返回结果
for (count = 0; count<m; count++)
{
int l, r, k;
cin >> l >> r >> k;//传入参数
q[count] = find(p, l, r, k);//查询m次
}
for (int i = 0; i<m; i++)//输出每次查询结果
{
cout << q[i] << endl;
}
return 0;
}


分析:
         根据输入格式第一行包含n个数,表示序列长度;

         第二行包含n个正整数,表示给定的序列;

         第三个包含一个正整数m,表示询问个数接下来的m行,每行三个数l,r,k,表示询问序列从左往右第l个数中,从大往小第k大的数是哪个。序列号元素从l开始标号。

 

根据样例输出我们可以知道输   m 组的   (l,r,k)们可以知道我们需要存储每组数据的返回值,所以函数类型不是 void
同样考虑到执行的次数为m次所以我们将循环m所以每次循环我们必须保证输入的参数没有被前面的影响,所以我们创建新的数组newbase来将指定的数据复制拷贝完毕

选择排序法的算法需要记住外层函数从第一个元素的下标开始,每次比较出这次的最小的数并和当前的循环数交换顺序

问题描述
  队列操作题。根据输入的操作命令,操作队列(1)入队、(2)出队并输出、(3)计算队中元素个数并输出。
输入格式
  第一行一个数字N。

  下面N行,每行第一个数字为操作命令(1)入队、(2)出队并输出、(3)计算队中元素个数并输出。
输出格式
  若干行每行显示一个2或3命令的输出结果。注意:2.出队命令可能会出现空队出队(下溢),请输出“no”,并退出。
样例输入
7

1 19

1 56

2

3

2

3

2
样例输出
19

1

56

0

no
数据规模和约定
  1<=N<=50

#include<iostream>
using namespace std;
//入对
//出队,并输出
//计算个数并输出

class queue
{
public:
queue();
~queue();
void push(int &n);
int pop();
int length();
bool empty();
private:
int *m_base;
int m_front;
int m_rear;
int m_size;
int m_length;
};
queue::queue()
{
m_front = m_rear=0;
m_size = 100;
m_base = new int[100];
}
queue::~queue()
{
delete []m_base;
}
int queue::length()
{
if (m_length>=0)
return m_length;
else
return -1;

}
void queue:: push(int &n)
{
m_base[m_rear] = n;
m_rear = (m_rear + 1) % m_size;
m_length++;
}
int queue::pop()
{

if (empty() == true)
return -1;
int p;
p = m_front;
m_front = (m_front + 1) % m_size;
--m_length;
return m_base[p];
}
bool queue::empty()
{
if (m_front == m_rear)return true;
else
return false;
}
int main()
{
int N;
cin >> N;//队列执行
int i;//循环次数
int cmd;//指令
queue que;
int *b = new int
;//存储指令
int *Num = new int
;//存储数据
int num;//入队的数
for (i = 0; i < N; i++)
{
cin >> cmd;
b[i] = cmd;
if (cmd == 1)
{
cin >> num;//
Num[i] = num;
}
else if(cmd==2||cmd==3)
Num[i] = 0;
}

for (i = 0; i < N; i++)
{

if (b[i] == 1)
{
que.push(Num[i]);
}

else if (b[i] == 2)
{
int z;
z = que.pop();//不能利用que.pop()判断因为每出现一次就会执行一次pop()出队
if (z >= 0)
cout << z << endl;
else
cout << "no" << endl;
}
else  if(b[i] == 3)
{
cout << que.length() << endl;
}

}
return 0;
}


十六进制转换十进制
问题描述
  从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。

  注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。
样例输入
       FFFF
样例输出 
      65535
思路  数字字符串我们采用string类型  , 数组的每个元素来遍历寻找 ,数组的元素可以分为两类----字母和数字分别进行判断,因为是字符型所以将字符转化为数字运用ASCII码来表示
#include<iostream>
#include<string>
using namespace std;
int main()
{
string num;//输入待转换的十六进制
cin >> num;

int size = num.size();//得到数组的长度
if (size>8||num=="FFFFFFFF")//判断是否越界长度越界以及超过最大十六进制的数字
return 0;

int i,j;//循环变量i
int count = 0;
long long sum=0,z=0;//十进制数字
for (i = size-1,count=0; i>=0,count<size; i--,count++)//第一个表示待转换的数据从小到大(从右到左)第一个用来记录当前是幂的数字
{
if (num[i] >= 'A'&&num[i] < 'Z')//如果是大于10的数字
{
long long z= num[i] - 'A' + 10;//当前字母的数字//由于是8位十六进制数字可能存在数据类型越界所以使用  long long 的数据类型  long long 是64位存储 然而int 是32位存储
for (j=0;j<count;j++)
{
z = z * 16;//对数据的幂指数进行处理计算
}
sum = sum + z;//数据统计求和
}
else//   !!!!!必须是else 如果是else if(num[i]>=0&&num[i]<=9)计算结果等于0
{
z = num[i]-'0';
for (j = 0; j<count; j++)
{
z = z * 16;
}
sum = sum + z;
}
}
cout << sum << endl;
return 0;
}


未名湖边的烦恼

登录后才能查看试题。

时间限制:1.0s   内存限制:256.0MB

锦囊1

锦囊2

锦囊3

问题描述
  每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。

  每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种排法)
输入格式
  两个整数,表示m和n
输出格式
  一个整数,表示队伍的排法的方案数。
样例输入
3 2
样例输出
5
数据规模和约定
  m,n∈[0,18]

  问题分析

#include<iostream>
using namespace std;
int f(int m,int n)
{
if(m<n)//如果此时租鞋的人数大于还鞋的人数
return 0;
if(n==0)// 租鞋的人数为0
return 1;
return f(m-1,n)+f(m,n-1);
}
int main()
{
int m,n;//m表示还鞋 n表示租鞋
cin>>m>>n;
cout<<f(m,n)<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息