1.煤球数目
有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),
....
如果一共有100层,共有多少个煤球?请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
这个题的思路就是,煤球堆是一个三棱锥,他从第二层开始,每一层都会比上一层多当前层数个,然后累加就好了。
#include<stdio.h>
int main()
{
int i = 0;
int num = 0;
int a[101] = { 0 };
for (i = 1; i < 101; i++)
{
a[i] = a[i - 1] + i;
num += a[i];
}
printf("%d", num);
return 0;
}
3.凑算式
B DEF
A + --- + ------- = 10
C GHI
(如果显示有问题,可以参见【图1.jpg】)
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
凑算式,感觉这个题难点就在于,这九个数字怎样分配的问题,有两种写法,一种是递推,一种是递归。重点就是这个题要用到回溯的思想,每一次退出当前循环的话,就要把计数器回到上一循环的状态中。
递推:(感觉递推的代码有点长,就是9个for循环嵌套,而且中间还很容易出错,表示写的时候就吃过这种亏,之后百度的时候,发现有递归的代码,就是dfs)
#include<stdio.h>
#include<string.h>
int arr[10] = { 0 };
int ans = 0;
int visit[10] = { 0 };
int judge(int* arr)
{
double x = arr[1] + (double)arr[2] / arr[3] + (double)(arr[4] * 100 + arr[5] * 10 + arr[6]) / (arr[7] * 100 + arr[8] * 10 + arr[9]);
if (x == 10)
{
return 1;
}
return 0;
}
int main()
{
int a, b, c, d, e, f, g, h, i;
for (a = 1; a <= 9; a++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
for (b = 1; b <= 9; b++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
if (arr[b] == 1)
{
continue;
}
arr[b] = 1;
for (c = 1; c <= 9; c++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
arr[b] = 1;
if (arr[c] == 1)
{
continue;
}
arr[c] = 1;
for (d = 1; d <= 9; d++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
arr[b] = 1;
arr[c] = 1;
if (arr[d] == 1)
{
continue;
}
arr[d] = 1;
for (e = 1; e <= 9; e++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
arr[b] = 1;
arr[c] = 1;
arr[d] = 1;
if (arr[e] == 1)
{
continue;
}
arr[e] = 1;
for (f = 1; f <= 9; f++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
arr[b] = 1;
arr[c] = 1;
arr[d] = 1;
arr[e] = 1;
if (arr[f] == 1)
{
continue;
}
arr[f] = 1;
for (g = 1; g <= 9; g++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
arr[b] = 1;
arr[c] = 1;
arr[d] = 1;
arr[e] = 1;
arr[f] = 1;
if (arr[g] == 1)
{
continue;
}
arr[g] = 1;
for (h = 1; h <= 9; h++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
arr[b] = 1;
arr[c] = 1;
arr[d] = 1;
arr[e] = 1;
arr[f] = 1;
arr[g] = 1;
if (arr[h] == 1)
{
continue;
}
arr[h] = 1;
for (i = 1; i <= 9; i++)
{
memset(arr, 0, sizeof(arr));
arr[a] = 1;
arr[b] = 1;
arr[c] = 1;
arr[d] = 1;
arr[e] = 1;
arr[f] = 1;
arr[g] = 1;
arr[h] = 1;
if (arr[i] == 1)
{
continue;
}
arr[i] = 1;
visit[1] = a;
visit[2] = b;
visit[3] = c;
visit[4] = d;
visit[5] = e;
visit[6] = f;
visit[7] = g;
visit[8] = h;
visit[9] = i;
if (judge(visit))
{
ans++;
}
}
}
}
}
}
}
}
}
}
printf("%d", ans);
return 0;
}
递归:
#include<stdio.h>
#include<string.h>
int arr[10] = { 0 };
int ans = 0;
int my_arr[10] = { 0 };
void slove()
{
double x = arr[1] + (double)arr[2] / arr[3] + (double)(arr[4] * 100 + arr[5] * 10 + arr[6]) / (arr[7] * 100 + arr[8] * 10 + arr[9]);
if (x == 10)
{
ans++;
}
}
void dfs(int index)
{
if (index == 10)
{
slove();
return;
}
int i = 0;
for (i = 1; i < 10; i++)
{
if (!my_arr[i])
{
my_arr[i] = 1;
arr[index] = i;
dfs(index + 1);
my_arr[i] = 0;
}
}
}
int main()
{
dfs(1);
printf("%d", ans);
return 0;
}
5.
抽签
X星球要派出一个5人组成的观察团前往W星。
其中:
A国最多可以派出4人。
B国最多可以派出2人。
C国最多可以派出2人。
....
那么最终派往W星的观察团会有多少种国别的不同组合呢?
下面的程序解决了这个问题。
数组a[] 中既是每个国家可以派出的最多的名额。
程序执行结果为:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
....
(以下省略,总共101行)
#include <stdio.h>
#define N 6
#define M 5
#define BUF 1024
void f(int a[], int k, int m, char b[])
{
int i,j;
if(k==N){
b[M] = 0;
if(m==0) printf("%s\n",b);
return;
}
for(i=0; i<=a[k]; i++){
for(j=0; j<i; j++) b[M-m+j] = k+'A';
//______________________; //填空位置
f(a, k + 1, m-i, b);
}
}
int main()
{
int a[N] = {4,2,2,1,1,3};
char b[BUF];
f(a,0,M,b);
return 0;
}
仔细阅读代码,填写划线部分缺少的内容。注意:不要填写任何已有内容或说明性文字。
9.交换瓶子
有N个瓶子,编号 1 ~ N,放在架子上。
比如有5个瓶子:
2 1 3 5 4
要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换2次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。
输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。
例如,输入:
5
3 1 2 5 4
程序应该输出:
3
再例如,输入:
5
5 4 3 2 1
程序应该输出:
2资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
一开始看到这个题,就想的是就是给这几个瓶子排个顺序就好了,但是写完之后发现时间太长了,再读一遍题才发现,瓶子标号是1-N,。。。。。这样用一个数组进行计数,然后一个遍历,for循环每循环一次,当前位置的瓶子就是正确的标号。这里感觉还有一个要注意的点就是交换的时候,如果新建一个变量进行交换的时候,会有一点点的慢,用异或的方式,以二进制的形式进行交换好一点。
#include<stdio.h>
int ans = 0;
int arr[10010] = { 0 };
int N = 0;
int i = 0;
void Exchange(int* a, int* b)
{
*a = *a^*b;
*b = *a^*b;
*a = *a^*b;
ans++;
}
int main()
{
scanf("%d", &N);
for (i = 1; i <= N; i++)
{
scanf("%d", &arr[i]);
}
for (i = 1; i <= N; i++)
{
while (arr[i] != i)
{
Exchange(&arr[i], &arr[arr[i]]);
}
}
printf("%d", ans);
return 0;
}
C
1.报纸页数
X星球日报和我们地球的城市早报是一样的,
都是一些单独的纸张叠在一起而已。每张纸印有4版。
比如,某张报纸包含的4页是:5,6,11,12,
可以确定它应该是最上边的第2张报纸。
我们在太空中捡到了一张X星球的报纸,4个页码分别是:
1125,1126,1727,1728
请你计算这份报纸一共多少页(也就是最大页码,并不是用了几张纸哦)?请填写表示总页数的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
看到这个题,我蒙了,百度之后才想起来,报纸的排版就时中间四页的顺序是连起来的,然后逐渐向两边递减和递增。。。。。
#include<stdio.h>
int main()
{
int a[4] = { 1125, 1126, 1727, 1728 };
int page = a[3] + a[0] + 1;
printf("%d", page);
return 0;
}
3.平方怪圈
如果把一个正整数的每一位都平方后再求和,得到一个新的正整数。
对新产生的正整数再做同样的处理。
如此一来,你会发现,不管开始取的是什么数字,
最终如果不是落入1,就是落入同一个循环圈。
请写出这个循环圈中最大的那个数字。
请填写该最大数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
一开始我就是求一个数字在循环过程中的最大数,结果突然发现数字越来越大。。。。。然后更改了一下思路,把数字没一次得到的数字都打印出来,然后暴力观察。。。。
#include<stdio.h>
int main()
{
int i = 0;
int a[1000] = { 0 };
int b[1000] = { 0 };
int n = 0;
scanf("%d", &n);
while (a[n] == 0 )
{
int sum = 0;
int num = n;
a[n] = 1;
while (num)
{
sum += (num % 10)*(num % 10);
num /= 10;
}
b[i] = sum;
i++;
n = sum;
}
int j = 0;
for (j = 0; j < i; j++)
{
printf("%d ", b[j]);
}
printf("%d", n);
return 0;
}
冰雹数
任意给定一个正整数N,
如果是偶数,执行: N / 2
如果是奇数,执行: N * 3 + 1
生成的新的数字再执行同样的动作,循环往复。
通过观察发现,这个数字会一会儿上升到很高,
一会儿又降落下来。
就这样起起落落的,但最终必会落到“1”
这有点像小冰雹粒子在冰雹云中翻滚增长的样子。
比如N=9
9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9的时候,这个“小冰雹”最高冲到了52这个高度。
输入格式:
一个正整数N(N<1000000)
输出格式:
一个正整数,表示不大于N的数字,经过冰雹数变换过程中,最高冲到了多少。
例如,输入:
10
程序应该输出:
52
再例如,输入:
100
程序应该输出:
9232资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
这个题有坑。。。N的意思就是从1到N,没一次冰雹变化的过程中,总体的最大值,而不是N的变化过程中的最大值。。
#include<stdio.h>
#include<string.h>
long long operation(long long number)
{
if (number % 2 == 0)
{
return number / 2;
}
return number * 3 + 1;
}
int main()
{
long long j = 0;
long long max = 0;
long N=0;
scanf("%ld", &N);
for (j = 1; j <= N; j++)
{
long long num = j;
while (num != 1)
{
num = operation(num);
if (num > max)
{
max = num;
}
}
}
printf("%lld\n", max);
return 0;
}