您的位置:首页 > 编程语言 > C语言/C++

蓝桥杯2014C语言A组赛题解析

2017-11-28 10:01 357 查看
切面条

   一根高筋拉面,中间切一刀,可以得到2根面条。 如果先对折1次,中间切一刀,可以得到3根面条。如果连续对折2次,中间切一刀,可以得到5根面条。那么,连续对折10次,中间切一刀,会得到多少面条呢?

对折次数n           面条根数f(n)
0               1
1               3
2               5

f(n)=f(n-1)+2^(n-1),n=2,3,...
f(n)=1,n=1


#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;

int fun(int x)
{
int i;
int s=1;
if(x == 1)
return 3;
else{
for(i=1;i<x;i++)
{
s=2*s;
}
return (s + fun(x-1));
}
}

int main()
{
int n;
scanf("%d",&n);
printf("%d\n",fun(n));

return 0;
}


李白打酒

   话说大诗人李白,一生好饮。 一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱: 无事街上走,提壶去打酒。 逢店加一倍,遇花喝一斗。这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)

#include <iostream>
#include <cstdio>
using namespace std;
int sum=0;
char str[100];
/*jiu:酒量
count:遇到店和花总次数
count_hua:遇到花次数
count_dian: 遇到店次数

遇到店和花递归搜索
fun(jiu-1,count+1,count_hua+1,count_dian);
fun(jiu*2,count+1,count_hua,count_dian+1);
*/
int fun(int jiu, int count,int count_hua, int count_dian)
{
int i;
if(jiu <0 || (jiu == 0 && count < 15)|| count >15)
return 0;
if(jiu==0 && count ==15 && count_hua==10 && count_dian==5)
{
sum++;
for(i=0;i<15;i++)
{
putchar(str[i]);
}
cout<<endl;
}

str[count]='a';
fun(jiu-1,count+1,count_hua+1,count_dian);

str[count]='b';
fun(jiu*2,count+1,count_hua,count_dian+1);
}
int main()
{

fun(2,0,0,0);
cout<<"sum:"<<sum<<endl;
return 0;
}


史丰收速算

史丰收速算法的革命性贡献是:从高位算起,预测进位。不需要九九表,彻底颠覆了传统手算! 速算的核心基础是:1位数乘以多位数的乘法。 其中,乘以7是最复杂的,就以它为例。因为,1/7 是个循环小数:0.142857…,如果多位数超过 142857…,就要进1。同理,2/7, 3/7, … 6/7 也都是类似的循环小数,多位数超过 n/7,就要进n

下面的程序模拟了史丰收速算法中乘以7的运算过程。 乘以 7 的个位规律是:偶数乘以2,奇数乘以2再加5,都只取个位。乘以 7 的进位规律是: 满 142857… 进1, 满 285714… 进2, 满 428571… 进3, 满 571428… 进4, 满 714285… 进5, 满 857142… 进6 请分析程序流程,填写划线部分缺少的代码。

#include <iostream>
#include <cstring>
using namespace std;
int ge_wei(int a)
{
if(a%2 == 0)
return (a*2)%10;
else
return (a*2+5)%10;
}

//每次取6位,等于0则一直比较下去
int jin_wei(char *p)
{
char *level[]={
"142857","285714","428571","571428","714285","857142"
};
char buf[7];
buf[6]='\0';
strncpy(buf,p,6);

int i;
for(i=5;i>=0;i--)
{
int r = strcmp(level[i], buf);
if(r<0)return i+1;

while(r==0){
p += 6;
strncpy(buf, p, 6);
r = strcmp(level[i], buf);
if(r<0)return i+1;

/*--------------------------*/
if(r>0) return i;
/*--------------------------*/
}
}
return 0;
}

//多位数*7
void f(char *s)
{
int head = jin_wei(s);
if(head>0)cout<<head;

char *p=s;
while(*p){
int a = (*p - '0');
int x = (ge_wei(a) + jin_wei(p+1))%10;
cout<<x;
p++;
}
cout<<endl;
}
int main()
{
f("428571428571");
f("34553834937543");
return 0;
}


打印图形

小明在X星球的城堡中发现了如下图形和文字,小明开动脑筋,编写了如下的程序,实现该图形的打印。



每个大三角形都可以分解为三个小三角形,递归分解直到分解成三个点,在这三个点所在坐标画星。注意点是,点的做小间隔应该是最小面一行每个间隔之间再加一个星。然后两个星之间的间隔为最小空隙。

a[][]为二维坐标系,rank为递归的层次,根据已经给出的两个递归相得出以三角形中哪个位置顶点代表三角形,以三角外接正方形的左上顶点表示三角形
/***************************/
fun(a,rank-1,row, col+w/2);
/***************************/
fun(a,rank-1,row+w/2, col);
fun(a,rank-1,row+w/2, col+w);


#include <iostream>
#include <cstdio>
using namespace std;
#define N 70

void fun(char a[]
, int rank, int row, int col)
{
if(rank == 1)
{
a[row][col]='*';
return;
}
int w =1;
int i;

for(i=0;i<rank-1;i++)
w*=2;
/***************************/
fun(a,rank-1,row, col+w/2);
/***************************/
fun(a,rank-1,row+w/2, col);
fun(a,rank-1,row+w/2, col+w);
}
int main()
{
char a

;
int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
a[i][j]=' ';
fun(a,5,0,0);

for(i=0;i<N;i++){
for(j=0;j<N;j++)
printf("%c",a[i][j]);
printf("\n");
}

return 0;
}


六角填数

如图所示六角形中,填入1~12的数字。 使得每条直线上的数字之和都相同。 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?



递归填数,每个位置有12种选择,已经填入的数字不在填,
1、7、10位置的数字固定直接填下一个数字。
填完12个判断六条线是否相等。


#include <iostream>
#include <cmath>
using namespace std;
int arr[15],have[15];
void fun(int i)
{
if(i==13)
{
int result[6];

result[0]=arr[1]+arr[2]+arr[3]+arr[4];
result[1]=arr[4]+arr[5]+arr[6]+arr[7];
result[2]=arr[7]+arr[8]+arr[9]+arr[1];
result[3]=arr[10]+arr[3]+arr[5]+arr[11];
result[4]=arr[11]+arr[6]+arr[8]+arr[12];
result[5]=arr[12]+arr[9]+arr[2]+arr[10];
int can_print=1;

for(int m=0;m<6;m++)
{
for(int n=m+1;n<6;n++)
if(result[m]!=result
)
can_print=0;
}
if(can_print)
{
for(int i =1;i<=12;i++)
{
cout<<"arr["<<i<<"]"<<arr[i];
cout<<endl;
}

}
}
if(i==1 ||i==7 || i==10)
fun(i+1);
if(!(i==1 ||i==7 || i==10))
{
for(int j=1;j<=12;j++)
{
if(!have[j])
{
arr[i]=j;
have[j]=1;
fun(i+1);
have[j]=0;
}
}
}
}
int main()
{
arr[1]=8;
arr[7]=3;
arr[10]=1;
have[1]=have[3]=have[8]=1;
fun(1);
return 0;
}


蚂蚁感冒

长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。

输入格式:

第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。

要求输出1个整数,表示最后感冒蚂蚁的数目。

需要保存的数据为蚂蚁感冒标记,蚂蚁当前位置(0-100厘米处位置和方向)
蚂蚁步长相同,可以定义循环每次所有蚂蚁向前加1(负方向都加1,相等于向左移)。

每次循环更新所有蚂蚁数据,相撞蚂蚁,(当前位置绝对值相同,方向相反),离开绳子 abs(ant[i].drec == 0) || abs(ant[i].drec > 100) 则数量--


#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef struct  _T{
int flag;
int drec;
}T;
int sum=1;
int main()
{
T ant[50];
int n,size;

scanf("%d",&n);

for(int i=0;i<n;i++)
{
scanf("%d",&(ant[i].drec));
if(i==0)
ant[i].flag=1;
else
ant[i].flag=0;
printf("ant[%d].srec=%d\tflag=%d\n",i,ant[i].drec,ant[i].flag);
}
size=n;

while(n){

for(int i=0;i<size;i++){
if(abs(ant[i].drec) >0)
ant[i].drec++;
if( abs(ant[i].drec == 0) || abs(ant[i].drec > 100) ){
n--;
}
}

for(int i=0;i<size;i++){
for(int j=i+1;j<size;j++){
if(abs(ant[i].drec) == abs(ant[j].drec)){
ant[i].drec=0-ant[i].drec;
ant[j].drec=0-ant[j].drec;
if(ant[i].flag + ant[j].flag == 1){
ant[i].flag=1;
ant[j].flag=1;
sum++;

d398
}

}
}
}

}
cout<<"sum:"<<sum<<endl;

return 0;
}


地宫取宝

X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。地宫的入口在左上角,出口在右下角。小明被带到地宫的入口,国王要求他只能向右或向下行走。走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。 当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。

【数据格式】

输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)

接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值

要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。

递归向下和向右搜索,走到出口(右下角)结束并判断
在当前位置需要判断该位置拿还是不拿


#include <stdio.h>
int sum=0;
int n,m,k;
int map[50][50];

//max保存当前拿到的最大值
int fun(int row, int col, int max, int nowHave)
{

if(row>=n || col >=m || nowHave>k)
return 0;
if(row==n-1 && col==m-1)
{
if(nowHave==k || (nowHave==k-1 && map[n-1][m-1] > max))
sum++;
}
if(map[row][col]>max)
{
fun(row+1, col, map[row][col],nowHave+1);
fun(row, col+1, map[row][col],nowHave+1);
}
fun(row+1, col, max,nowHave);
fun(row, col+1, max,nowHave);
}
int main()
{
int i,j;
scanf("%d%d%d", &n,&m,&k);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&map[i][j]);

fun(0,0,0,0);
printf("sum:%d\n",sum);
return 0;
}


小朋友排队

n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。

每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。

如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。

请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。

如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。

【数据格式】

输入的第一行包含一个整数n,表示小朋友的个数。

第二行包含 n 个整数 H1 H2 „ Hn,分别表示每个小朋友的身高。

输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。

需要保存每个小朋友的身高和交换的次数(生气值根据交换次数求出),
从低到高排序,依次找到当前最前面的小朋友需要交换的次数。


#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef struct _People{
int tall;
int step;
}People;
bool mycompare(People m,People n){
return m.tall < n.tall;
}
People be_sort[10000],af_sort[10000];

int shengqi(int step)
{
int sum=0;
for(int i=0;i<=step;i++)
{
sum+=i;
}
return sum;
}
int main()
{
int n;
int j;
int sum=0;
People temp;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&be_sort[i].tall);
af_sort[i]=be_sort[i];
}

sort(af_sort,af_sort+n,mycompare);
for(int i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
if(be_sort[j].tall==af_sort[i].tall)
break;
}

temp = be_sort[j];

temp.step+=j-i;
for(;j>i;j--)
{
be_sort[j-1].step++;
be_sort[j]=be_sort[j-1];
//be_sort[j].step++;
}
be_sort[i]=temp;
}

for(int i=0;i<n;i++)
{
sum+=shengqi(be_sort[i].step);
}
printf("%d\n",sum);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  蓝桥杯C-C++A组