一、关于头文件
//万能头文件#include<bits/stdc++.h>
1、#include<cstring>: strlen, strcmp, strcat, strcpy, memset ,substr
(1)memset(dp,0,sizeof(dp)); //一般用于给数组清零
函数原型: void *memset(void *s, int ch, size_t n);
(2)取子字符串 : substr(start [, length ])
2、#include<cmath>: double fabs()
3、#include<algorithm>: max, min, int abs, swap, reverse, sort,
lower_bound( begin,end,num), upper_bound( begin,end,num)
(1)reverse( v.begin() , v.end() )
(2)sort(start,end,排序方法)
在从小到大的排序数组中:先用sort排序,默认从小到大sort(a,a+10); // 第二个是最后一位要排序的地址的下一地址
#include<algorithm>
int main() {
int a[10]={9,6,3,8,5,2,7,4,1,0};
for(int i=0;i<10;i++)
cout<<a[i]<<endl;
sort(a,a+10);}// 第二个是结束的地址(最后一位要排序的地址的下一地址)
从大到小:sort(a,a+10,compare);
#include<algorithm> bool compare(int a,int b) { return a>b; } int main() { int a[10]={9,6,3,8,5,2,7,4,1,0}; for(int i=0;i<10;i++) cout<<a[i]<<endl; sort(a,a+10,compare);//在这里就不需要对compare函数传入参数了, //这是规则 |
(3)
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
4、#include<stdlib.h>:malloc()、rand()、free()、system()
二、题型
结果填空 题目描述一个具有确定解的问题。要求选手对问题的解填空。 不要求解题过程,不限制解题手段(可以使用任何开发语言或工具, 甚至是手工计算), 只要求填写最终的结果
解题:
1.(1)关于日期:一般用Excel加手算,关于(闰年、平年)
(2)求数目:一般是现实的问题,买东西之类的,注意类型、精度
例子:啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。
我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。
思路:循环遍历,注意精度问题,!!将钱数乘10计算。
例子:
海盗比酒量 浮点数比较
有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了。再打开一瓶酒平分,又有倒下的,再次重复...... 直到开了第4瓶酒,坐着的已经所剩无几,海盗船长也在其中。当第4瓶酒平分喝下后,大家都倒下了。
船长写到:“......昨天,我正好喝了一瓶..
请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人没倒下。
例如,有一种可能是:20,5,4,2,0
多个答案排列顺序不重要。
答案写在“解答.txt”中,不要写在这里!
参考答案:
18,9,3,2,0 (1分)
15,10,3,2,0 (2分)
20,5,4,2,0 (0分)
12,6,4,2,0 (2分)
问题的核心就是海盗船长正好喝了一瓶酒,假设每一轮中的人数为n,a,b,c,那么船长喝的酒就是1/n+1/a+1/b+1/c,如果结果为1,那么就可能是一组解,因为还要保证一些附加条件,首先要n>a>b>c,然后就是在判断1的时候,因为使用的double并不是一个分数,而是一个小数,所以精度肯定会下降,因此只要保证sum-1.0<0.0000001就可以了。或者通分(即分子,分母相等)
int main()
{
int n,a,b,c;
for(n=1;n<=20;n++) {
for(a=1;a<=20;a++) {
if(a<n)
for(b=1;b<=20;b++) {
if(b<a)
for(c=1;c<=20;c++) {
if(c<b) {
//double sum=1.0/n+1.0/a+1.0/b+1.0/c;
//if(abs(sum-1.0)<0.0000001) 或
if(n*a*b*c==a*b*c + n*b*c + n*a*c + n*a*b) {
cout<<n<<' '<<a<<' '<<b<<' '<<c<<endl; }
2、3
一般是:关于多个数相不相等:优先 && 或 ||加continue
例子:
int a,b,c,d,e,f,g,h;
for(a=1;a<=9;a++)
for(b=0;b<=9;b++) {
if(a!=b)
for(c=0;c<=9;c++) {
if(c!=a&&c!=b)
for(d=0;d<=9;d++) {
if(d!=a&&d!=b&&d!=c)
for(e=1;e<=9;e++) {
if( e!=a && e!=b && e!=c && e!=d)
for( f=0; f<=9; f++) {
if(f!=a && f!=b && f!=c && f!=d && f!=e)
for(g=0; g<=9; g++) {
if(g!=a && g!=b && g!=c && g!=d && g!=e && g!=f)
for(h=0; h<=9; h++) {
if(h!=a && h!=b && h!=c && h!=d && h!=e && h!=f && h!=g && (1000*a+100*b+10*c+d+1000*e+100*f+10*g+b)==(10000*e+1000*f+100*c+10*b+h))
cout<<e<<' '<<f<<' '<<g<<' '<<b<<endl;
}
等差数列 Sn=[ n*( a1 + an ) ] /2 一般是1,2,3... 则为 n*(n+1) /2
代码填空题 只填写空缺部分,不要填写完整句子。 不要写注释、说明 或其它题目中未要求的内容。所填代码应该具有通用性,不能只对 题面中给出的特殊示例有效。
解题:
先直接粘贴代码,使其运行,观察运行结果。
一般是动态规划其实也包括递归,对一个函数名或数组名做a[i+-1][j+-1]或其他变化; 回溯:互换后一般可能要换回
一些题目的答案:
14:(1)if(r>0)return i (2) f(a,rank-1,row, col + w/2)
15:(1)(width-strlen(s)-2)/2,"",buf,(width-strlen(s)-1)/2,""
(2){t=x[k]; x[k]=x[i]; x[i]=t;}
16:(1)swap(a,p,j) (2)f(a,k+1,m-i,b)
17:a[i][j]=a[i-1][j-1]+1 18: quick_select(a, i+1, r, k-(i-l+1))
动态规划:
数字三角形问题
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
从顶部向下走,每次只能走下面或者右下,走完全程,问你怎么走使得权值最大
dp【i】【j】:代表从第i行第j列出发得到的最优值
dp【i】【j】=max(dp【i+1】【j】,dp【i+1】【j+1】)+a【i】【j】
编程大题 题目一般要用到标准输入和输出。 题目一般会给出示例数据。 一般题目的难度主要集中于对算法的设计和逻辑的组织上。 选手给出的解法应具有普遍性,不能只适用于题目的示例数据(当然,至少应该适用于题目的示例数据)。为了测试选手给出解法的性能,评分时用的测试用例可能包含大数据量的压力测试用例,选手选择算法时要尽可能考虑可行性和效率 问题
解题:
一般第一道会简单。
枚举、搜索、模拟是蓝桥杯中数量最多的题目类别
//输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
// #include<iostream>
// #include<stdio.h>
// #include<string.h>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i,r=0,max,lena,lenb;
char s1[100],s2[100];
int a[100],b[100];
gets(s1);gets(s2);
lena=strlen(s1);lenb=strlen(s2);
for(i=0;i<lena;i++) a[i]=s1[lena-i-1]-'0';
for(i=0;i<lenb;i++) b[i]=s2[lenb-i-1]-'0';//将s1,s2分别倒序赋给a,b(高精度加法是从末位开始往前加)
if(lena>=lenb) max=lena;
else max=lenb;
if(lena>lenb) for(i=lenb;i<lena;i++) b[i]=0;
if(lena<lenb) for(i=lena;i<lenb;i++) a[i]=0;//当a,b位数不同时,给位数少的赋0,保证后面的运算
int c[102];
for(i=0;i<max;i++)
{ c[i]=r+a[i]+b[i];
c[i]=c[i]%10;
r=c[i]/10;
}
while(r!=0)
{max++;
c[max-1]=r%10;
r=r/10;
}
for(i=max-1;i>=0;i--) cout<<c[i];
cout<<endl;
return 0;
}
进制转换:
// 十进制转十六进制
//思路:不断的取余(之前在纸上写的阶梯式算式,最后从下往上取数)
#include <iostream>
using namespace std;
int main()
{
long long a;char s[10];int i=0,c=0,temp;//temp是int,s[]是char!!!
cin>>a;
if(a==0) cout<<0<<endl;
while(a!=0)
{
temp=a%16;c++;
if(temp>=10) s[i++]=temp-10+'A';
else s[i++]=temp+'0';//要看什么类型相加减,有int与char相加减,char会自动转成数字,输出的则看定义的是什么类型,再转化
a=a/16;
}
for(i=c-1;i>=0;i--) cout<<s[i];
cout<<endl;
return 0;
}
// 十六进制转十进制
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
int main( )
{
char a[8]; gets(a);
int i,c=strlen(a);long long t=0;//注意输出的是否够空间
for(i=0;i<c;i++)
{
if(a[i]>='0'&&a[i]<='9') a[i]=a[i]-'0';//不能省,因为如果没有这步,当a[i]=0时,下面会转成48与之相乘
else a[i]=10+(a[i]-'A');//字符型的比较要注意,注意必须是要用到才能写,不能提前写
//这里的if else 不能放在前面!!!
t=t+a[i]*pow(16,c-i-1);
}
cout<<t<<endl;
return 0;}
//十六进制转八进制
#include<iostream>
#include<cstring>
using namespace std;
int main()
{ string s1,s2;//s1存输入的十六进制,s2存二进制
int n; int i,j,k;
cin>>n;
for(i=0;i<n;i++)
{ cin>>s1; s2="";//对s2初始化
for(j=0;j<s1.length();j++)
{ switch(s1[j])
{ case '0':s2+="0000";break;
case '1':s2+="0001";break;
case '2':s2+="0010";break;
case '3':s2+="0011";break;
case '4':s2+="0100";break;
case '5':s2+="0101";break;
case '6':s2+="0110";break;
case '7':s2+="0111";break;
case '8':s2+="1000";break;
case '9':s2+="1001";break;
case 'A':s2+="1010";break;
case 'B':s2+="1011";break;
case 'C':s2+="1100";break;
case 'D':s2+="1101";break;
case 'E':s2+="1110";break;
case 'F':s2+="1111";break;
default:break; }
}
if(s2.length()%3==1)
s2="00"+s2;
if(s2.length()%3==2)
s2="0"+s2;
int flag=0;
for(k=0;k<s2.length()-2;k+=3)
{ int p=4*(s2[k]-'0')+2*(s2[k+1]-'0')+s2[k+2]-'0';
if(p) flag=1; //去掉前导,而且如果后面有0,那么前面已经使得 flag=1,所以能够输出
if(flag) cout<<p; //如果只有 if(p) cout<<p;那么后面有0就输不出
}
cout<<endl;
}
return 0;
}
注:
const int MAXN = 100005;
int a[MAXN],b[MAXN],c[MAXN];
int n,sum;
int main() //当数组比较大时定义在main函数之外
return; 的作用相当于 break; 用于中断循环的作用,而 return 0; 则是return的另一种用法,专用于返回值非void的函数返回其值。