第七届蓝桥杯A组C

1.网友年龄

某君新认识一网友。
当问及年龄时,他的网友说:
我的年龄是个2位数,我比儿子大27岁,
如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄”

请你计算:网友的年龄一共有多少种可能情况?

提示:30岁就是其中一种可能哦.

请填写表示可能情况的种数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

#include<stdio.h>

int main()
{
    int age = 2;
    int num = 0;
    for (age = 2; age < 73; age++)
    {
        if ((age % 10 * 10 + age / 10)==age+27)
        {
            num++;
            //printf("age=%2d,age+27=%2d\n", age, age + 27);
        }
    }
    printf("%d\n", num);
    return 0;
}

2.生日蜡烛

某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。

现在算起来,他一共吹熄了236根蜡烛。

请问,他从多少岁开始过生日party的?

请填写他开始过生日party的年龄数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。 

int main()
{
	int age = 1;
	int count = 0;
	for (age = 1;age<236; age++)
	{
		int num = 236;
		count = age;
		int n = 0;
		while (num > n)
		{
			n += count;
			count++;
		}
		if (n == num)
		{
			printf("%d\n", age);
		}
	}
	return 0;
}

3.方格填数

如下的10个格子
   +--+--+--+
   |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |
+--+--+--+

(如果显示有问题,也可以参看【图1.jpg】)

填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

思路就是用递归对每个方格进行遍历,再进行判断。递归的时候for循环的控制变量一定不能用全局变量 。

#include<stdio.h>
#include<math.h>

int ans = 0;
int my_arr[10] = { 0 };
int arr[10] = { 0 };
int visit[3][4] = { 0 };
int count = 0;
int dir[8][2] = { 0, -1, 0, 1, 1, 0, -1, 0, 1, 1, 1, -1, -1, -1, -1, 1 };
//表示周围的位置

int judge(const int x,const int y)
{
	int i = 0;
	int tx = 0;
	int ty = 0;
	for (i = 0; i < 8; i++)
	{
		tx = x + dir[i][0];
		ty = y + dir[i][1];
		if ((tx<0) || (tx>2) || (ty<0) || (ty>3))
		{
			continue;
		}
		if (visit[tx][ty] == -10)
		{
			continue;
		}
		if (abs(visit[tx][ty] - visit[x][y] == 1))
		{
			return 0;
		}
	}
	return 1;
}

void slove()
{
	int i = 0;
	int j = 0;
	int n = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			if ((i == 0 && j == 0) || (i == 2 && j == 3))
			{
				visit[i][j] = -10;
			}
			else
			{
				visit[i][j] = arr[n];
				n++;
			}
		}
	}
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			if ((i == 0 && j == 0) || (i == 2 && j == 3))
			{
				continue;
			}
			else
			{
				if (!judge(i,j))
				{
					return;
				}
			}
		}
	}
	ans++;
}


void dfs(int index)
{
	if (index == 10)
	{
		slove();
		return;
	}
	else
	{
		int i = 0;
		for (i = 0; i <= 9; i++)
		{
			if (!my_arr[i])
			{
				my_arr[i] = 1;
				arr[count] = i;
				count++;
				dfs(index + 1);
				arr[count] = 0;
				count--;
				my_arr[i] = 0;
			}
		}
	}
}

int main()
{
	dfs(0);
	printf("%d", ans);
	return 0;
}

4.快速排序

排序在各种场合经常被用到。
快速排序是十分常用的高效率的算法。
其思想是:先选一个“标尺”,
用它把整个队列过一遍筛子,
以保证:其左边的元素都不大于它,其右边的元素都不小于它。
这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。
下面的代码是一种实现,请分析并填写划线部分缺少的代码。

#include <stdio.h>

void swap(int a[], int i, int j)
{
    int t = a[i];
    a[i] = a[j];
    a[j] = t;
}

int partition(int a[], int p, int r)
{
    int i = p;
    int j = r + 1;
    int x = a[p];
    while (1){
        while (i<r && a[++i]<x);
        while (a[--j]>x);
        if (i >= j) break;
        swap(a, i, j);
    }
    //______________________;
    swap(a, p, j);
    return j;
}

void quicksort(int a[], int p, int r)
{
    if (p<r){
        int q = partition(a, p, r);
        quicksort(a, p, q - 1);
        quicksort(a, q + 1, r);
    }
}

int main()
{
    int i;
    int a[] = { 5, 13, 6, 24, 2, 8, 19, 27, 6, 12, 1, 17 };
    int N = 12;

    quicksort(a, 0, N - 1);

    for (i = 0; i<N; i++) printf("%d ", a[i]);
    printf("\n");

    return 0;
}

5.消除尾一

下面的代码把一个整数的二进制表示的最右边的连续的1全部变成0
如果最后一位是0,则原数字保持不变。

如果采用代码中的测试数据,应该输出:
00000000000000000000000001100111   00000000000000000000000001100000
00000000000000000000000000001100   00000000000000000000000000001100

请仔细阅读程序,填写划线部分缺少的代码。

#include <stdio.h>

void f(int x)
{
    int i;
    for (i = 0; i<32; i++) printf("%d", (x >> (31 - i)) & 1);
    printf("   ");

    //x = _______________________;
    x = x&(x+1);
    for (i = 0; i<32; i++) printf("%d", (x >> (31 - i)) & 1);
    printf("\n");
}

int main()
{
    f(103);
    f(12);
    return 0;
}

6.寒假作业

现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:

   □ + □ = □
   □ - □ = □
   □ × □ = □
   □ ÷ □ = □
   
   (如果显示不出来,可以参见【图1.jpg】)
   
每个方块代表1~13中的某一个数字,但不能重复。
比如:
 6  + 7 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

以及: 
 7  + 6 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

就算两种解法。(加法,乘法交换律后算不同的方案)
 
你一共找到了多少种方案?
当时想这个题的时候,没想到那些简单点的算法,只想遍历解决一遍,可能代码看上去会有那么一点不精简。。

#include<stdio.h>

void bianli(int* a)
{
	int i = 0;
	for (i = 0; i <= 13; i++)
	{
		a[i] = 1;
	}
}
int main()
{
	int add = 0;
	int sub = 0;
	int mul= 0;
	int div = 0;
	int count = 0;
	int i = 0;
	int j = 0;
	int m = 0;
	int n = 0;
	for (add =1; add <= 13; add++)
	{
		int a[14] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
		for (i = 1; i <= 13-add; i++)
		{
			bianli(a);
			a[add] = 0;
			if ((a[i] != 1) || (a[add+i]!=1))
			{
				continue;
			}
			for (sub = 13; sub >0; sub--)
			{
				bianli(a);
				a[add] = 0;
				a[i] = 0;
				a[add + i] = 0;
				if (a[sub]!= 1)
				{
					continue;
				}
				for (j = 1; j <sub; j++)
				{
					bianli(a);
					a[add] = 0;
					a[i] = 0;
					a[add + i] = 0;
					a[sub] = 0;
					if (a[j] != 1)
					{
						continue;
					}
					a[j] = 0;
					if (a[sub - j] != 1)
					{
						continue;
					}
					for (mul = 1; mul <= 13; mul++)
					{
						bianli(a);
						a[add] = 0;
						a[i] = 0;
						a[add + i] = 0;
						a[sub] = 0;
						a[j] = 0;
						a[sub - j] = 0;
						if (a[mul] != 1)
						{
							continue;
						}
						for (m = 1; m <= (13/mul); m++)
						{
							bianli(a);
							a[add] = 0;
							a[i] = 0;
							a[add + i] = 0;
							a[sub] = 0;
							a[j] = 0;
							a[sub - j] = 0;
							a[mul] = 0;
							if (a[m] != 1) 
							{
								continue;
							}
							a[m] = 0;
							if  (a[m*mul] != 1)
							{
								continue;
							}
							for (div = 13; div > 0; div--)
							{
								bianli(a);
								a[add] = 0;
								a[i] = 0;
								a[add + i] = 0;
								a[sub] = 0;
								a[j] = 0;
								a[sub - j] = 0;
								a[m] = 0;
								a[mul] = 0;
								a[m*mul] = 0;
								if (a[div] != 1)
								{
									continue;
								}
								a[div] = 0;
								for (n = 1; n < div; n++)
								{
									bianli(a);
									a[add] = 0;
									a[i] = 0;
									a[add + i] = 0;
									a[sub] = 0;
									a[j] = 0;
									a[sub - j] = 0;
									a[m] = 0;
									a[mul] = 0;
									a[m*mul] = 0;
									a[div] = 0;
									if ((div%n )!= 0)
									{
										continue;
									}
									if (a[n] != 1)
									{
										continue;
									}
									a[n] = 0;
									if (a[div/n] != 1)
									{
										continue;
									}
									count++;
									//printf("%d+%d=%d\n", add, i, add + i);
									//printf("%d-%d=%d\n", sub, j, sub-j);
									//printf("%d*%d=%d\n", mul, m, mul*m);
									//printf("%d/%d=%d\n", div, n, div/n);
									//printf("\n");
								}
							}
						}
					}
				}
			}
		}
	}
	printf("%d\n", count);
	return 0;
} 

7.剪邮票

如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

递推实现: 

#include<stdio.h>
#include<string.h>

int mip[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
int count = 0;
int have[13] = { 0 };//记录五个邮票的位置
int visit[3][4] = { 0 };//判断该邮票是否已经符合
int dir[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
//当前邮票的上下左右位置

void find(const int x, const int y)
{
	int i = 0;
	int tx, ty;
	for (i = 0; i<4; i++)
	{
		tx = x + dir[i][0];
		ty = y + dir[i][1];
		if ((tx<0) || (tx >= 3) || (ty<0) || (ty >= 4))
		{
			continue;
		}
		if ((have[mip[tx][ty]] == 0)|| visit[tx][ty])
        //如果该位置没有邮票或者已经判断过了,就跳出
		{
			continue;
		}
		visit[tx][ty] = 1;
		count++;
		find(tx, ty);
	}
}

int slove(const int i, const int j, const int k, const int m, const int n)
{
	count = 0;
	memset(have, 0, sizeof(have));
	int a[5] = { i, j, k, m, n };
	memset(visit, 0, sizeof(visit));
	int num = 0;
	for (num = 0; num<5; num++)
	{
		have[a[num]] = 1;
	}
	int x, y;
	x = i / 4;
	y = i % 4-1;
	if (i % 4 == 0)
	{
		x -= 1;
		y = 3;
	}
	count = 1;
	visit[x][y] = 1;
	find(x, y);
	if (count == 5)
	{
		return 1;
	}
	return 0;
}

int main()
{
	int i = 0;
	int j = 0;
	int k = 0;
	int m = 0;
	int n = 0;
	int ans = 0;
	for (i = 1; i<9; i++)
	{
		for (j = i + 1; j<10; j++)
		{
			for (k = j + 1; k<11; k++)
			{
				for (m = k + 1; m<12; m++)
				{
					for (n = m + 1; n<13; n++)
					{
						if (slove(i, j, k, m, n))
						{
							ans++;
							//printf("%d %d %d %d %d\n", i, j, k, m, n);
						}
					}
				}
			}
		}
	}
	printf("%d", ans);
	return 0;
}

8.四平方和

四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。

比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)

对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序:
0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法


程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开

例如,输入:
5
则程序应该输出:
0 0 1 2

再例如,输入:
12
则程序应该输出:
0 2 2 2

再例如,输入:
773535
则程序应该输出:
1 1 267 838

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 3000ms

#include<stdio.h>
#include<math.h>


int main()
{
	int num = 0;
	int count = 0;
	int i = 0;
	scanf("%d", &num);
	int i1 = 0, i2 = 0, i3 = 0;
	int x1 = sqrt(num / 4) + 1;
	int x2 = sqrt(num / 3) + 1;
	int x3 = sqrt(num / 2) + 1;
	for (i1 = 0; i1 <= x1; i1++)
	{
		for (i2 = i1; i2 <= x2; i2++)
		{
			for (i3 = i2; i3 <= x3; i3++)
			{
				int x4 = num - i1*i1 - i2*i2 - i3*i3;
				if (x4 == (int)sqrt(x4)*(int)sqrt(x4) && (int)sqrt(x4)>=x3)
				{
					printf("%d %d %d %d\n", i1, i2, i3, (int)sqrt(x4));
					exit();
				}
			}
		}
	}
	return 0;
} 

9.密码脱落(放弃)

X星球的考古学家发现了一批古代留下来的密码。
这些密码是由A、B、C、D 四种植物的种子串成的序列。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。

你的任务是:
给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。

输入一行,表示现在看到的密码串(长度不大于1000)
要求输出一个正整数,表示至少脱落了多少个种子。

例如,输入:
ABCBA
则程序应该输出:
0

再例如,输入:
ABDCDCBABC
则程序应该输出:
3

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

 

10.最大比例(放弃)

X星球的某个大奖赛设了M级奖励。每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。比如:
16,24,36,54
其等比值为:3/2

现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。

输入格式:
第一行为数字 N (0<N<100),表示接下的一行包含N个正整数
第二行N个正整数Xi(Xi<1 000 000 000 000),用空格分开。每个整数表示调查到的某人的奖金数额

要求输出:
一个形如A/B的分数,要求A、B互质。表示可能的最大比例系数

测试数据保证了输入格式正确,并且最大比例是存在的。

例如,输入:
3
1250 200 32

程序应该输出:
25/4

再例如,输入:
4
3125 32 32 200

程序应该输出:
5/2

再例如,输入:
3
549755813888 524288 2

程序应该输出:
4/1

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 3000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码

 

发布了23 篇原创文章 · 获赞 126 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览