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
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码