题目标题: 猜年龄
美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。
一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,他回答说:
“我年龄的立方是个4位数。我年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”
请你推算一下,他当时到底有多年轻。
通过浏览器,直接提交他那时的年龄数字。
注意:不要提交解答过程,或其它的说明文字。
答案:18
#include <bits/stdc++.h>
using namespace std;
int vis[10];
bool Judge (int k) {
int a = k*k*k;
int b = k*k*k*k;
if (a >=1000 && a <= 9999 && b >= 100000 && b <= 999999) {
memset(vis, 0, sizeof(vis));
for (int i = 0; i < 4; i++) {
vis[a%10]++;
a /= 10;
}
for (int i = 0; i < 6; i++) {
vis[b%10]++;
b /= 10;
}
for (int i = 0; i < 10; i++) {
if (vis[i] != 1) {
return false;
}
}
return true;
}
return false;
}
int main() {
for (int i = 10; i <= 99; i++) {
if (Judge(i)) {
printf("%d\n",i);
}
}//18
return 0;
}
标题: 马虎的算式
小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。
有一次,老师出的题目是:36 x 495 = ?
他却给抄成了:396 x 45 = ?
但结果却很戏剧性,他的答案竟然是对的!!
因为 36 * 495 = 396 * 45 = 17820
类似这样的巧合情况可能还有很多,比如:27 * 594 = 297 * 54
假设 a b c d e 代表1~9不同的5个数字(注意是各不相同的数字,且不含0)
能满足形如: ab * cde = adb * ce 这样的算式一共有多少种呢?
请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
答案直接通过浏览器提交。
注意:只提交一个表示最终统计种类数的数字,不要提交解答过程或其它多余的内容。
答案:142(暴力枚举)
标题: 振兴中华
小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:(也可参见p1.jpg)
从我做起振
我做起振兴
做起振兴中
起振兴中华
比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。
要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
答案是一个整数,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。
答案:35(递推或者直接搜索编码一下)
<mark>dp[i][j] = dp[i-1][j] + dp[i][j-1] (dp[0][i] = dp[i][0] = 1)</mark>
#include <bits/stdc++.h>
using namespace std;
/* 从我做起振 我做起振兴 做起振兴中 起振兴中华 */
char img[5][6]={
"12345",
"23456",
"34567",
"45678"
};
int nxt[2][2] = {0,1,1,0};
int DFS(int x, int y, char bef) {
if (x == 3 && y == 4) {
return 1;
}
int ans = 0;
for (int i = 0; i < 2; i++) {
int nx = x + nxt[i][0];
int ny = y + nxt[i][1];
if (x > 3 || x < 0 || y > 4 || y < 0) {
continue;
}
if (img[nx][ny] == img[x][y] + 1) {
ans += DFS(nx, ny, img[nx][ny]);
}
}
return ans ;
}
int main() {
cout << DFS(0, 0, '0') << endl;
return 0;
}
标题: 幻方填空
幻方是把一些数字填写在方阵中,使得行、列、两条对角线的数字之和都相等。
欧洲最著名的幻方是德国数学家、画家迪勒创作的版画《忧郁》中给出的一个4阶幻方。
他把1,2,3,...16 这16个数字填写在4 x 4的方格中。
如图p1.jpg所示,即:
16 ? ? 13
? ? 11 ?
9 ? ? *
? 15 ? 1
表中有些数字已经显露出来,还有些用?和*代替。
请你计算出? 和 * 所代表的数字。并把 * 所代表的数字作为本题答案提交。
答案是一个整数,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。
答案:暴力搜索一下,或者可以利用幻方的构造方法直接手算,搜索的话注意编码一下,搜10个数就够了,也就是搜索深度只有10
#include <bits/stdc++.h>
using namespace std;
int val[16],vis[17],dis[16];
bool Judge () {
int sum[2][4],b,c;
b = c = 0;
memset(sum, 0, sizeof(sum));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
if (i == 0) {
sum[i][j] += val[j*4+k];
}else {
sum[i][j] += val[j+k*4];
}
}
if (sum[i][j] != sum[0][0]) {
return false;
}
}
}
for (int i = 0; i < 4; i++) {
b += val[i*5];
c += val[3+3*i];
}
if (b != sum[0][0] || c != sum[0][0]) {
return false;
}
return true;
}
void DFS (int idx) {
if (idx == 16) {
if (Judge()) {
cout << val[11] << endl;
system("pause");
}
return ;
}
if (dis[idx] == 1) {
DFS(idx+1);
}else {
for (int i = 1; i <= 16; i++) {
if (vis[i] == 0) {
vis[i] = 1;
dis[idx] = 1;
val[idx] = i;
DFS(idx+1);
dis[idx] = 0;
vis[i] = 0;
}
}
}
}
int main() {
memset(dis, 0, sizeof(dis));
memset(vis, 0, sizeof(vis));
val[0] = 16; dis[0] = 1; vis[16] = 1;
val[3] = 13; dis[3] = 1; vis[13] = 1;
val[6] = 11; dis[6] = 1; vis[11] = 1;
val[8] = 9; dis[8] = 1; vis[9] = 1;
val[13] = 15; dis[13] = 1; vis[15] = 1;
val[15] = 1; dis[15] = 1; vis[1] = 1;
DFS(0); //12
return 0;
}
题目标题:公约数公倍数
我们经常会用到求两个整数的最大公约数和最小公倍数的功能。
下面的程序给出了一种算法。
函数 myfunc 接受两个正整数a,b
经过运算后打印出 它们的最大公约数和最小公倍数。
此时,调用 myfunc(15,20)
将会输出:
5
60
// 交换数值
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
void myfunc(int a, int b)
{
int m,n,r;
if(a<b) swap(&a,&b);
m=a;n=b;r=a%b;
while(r!=0)
{
a=b;b=r;
r=a%b;
}
printf("%d\n",b); // 最大公约数
printf("%d\n", ____________________________________); // 最小公倍数
}
请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!
答案:n*m/b
标题:三部排序
一般的排序有许多经典算法,如快速排序、希尔排序等。
但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。
比如,对一个整型数组中的数字进行分类排序:
使得负数都靠左端,正数都靠右端,0在中部。注意问题的特点是:负数区域和正数区域内并不要求有序。可以利用这个特点通过1次线性扫描就结束战斗!!
以下的程序实现了该目标。
其中x指向待排序的整型数组,len是数组的长度。
void sort3p(int* x, int len)
{
int p = 0;
int left = 0;
int right = len-1;
while(p<=right){
if(x[p]<0){
int t = x[left];
x[left] = x[p];
x[p] = t;
left++;
p++;
}
else if(x[p]>0){
int t = x[right];
x[right] = x[p];
x[p] = t;
right--;
}
else{
__________________________; //填空位置
}
}
}
如果给定数组:
25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0
则排序后为:
-3,-2,-16,-5,0,0,0,21,19,33,25,16,18,25
请分析代码逻辑,并推测划线处的代码,通过网页提交
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!
答案:p++
标题:核桃的数量
小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:
1. 各组的核桃数量必须相同
2. 各组内必须能平分核桃(当然是不能打碎的)
3. 尽量提供满足1,2条件的最小数量(节约闹革命嘛)
程序从标准输入读入:
a b c
a,b,c都是正整数,表示每个组正在加班的人数,用空格分开(a,b,c<30)
程序输出:
一个正整数,表示每袋核桃的数量。
例如:
用户输入:
2 4 5
程序输出:
20
再例如:
用户输入:
3 1 1
程序输出:
3
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
最小公倍数
#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a%b);
}
int lcm(int a, int b) {
return a*b/gcd(a,b);
}
int main() {
int a,b,c;
cin >> a >> b >> c;
cout << lcm(a,lcm(b,c)) << endl;
return 0;
}
题目标题:打印十字图
小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示(可参见p1.jpg)
$$$$$$$$$$$$$
$ $
$$$ $$$$$$$$$ $$$
$ $ $ $
$ $$$ $$$$$ $$$ $
$ $ $ $ $ $
$ $ $$$ $ $$$ $ $
$ $ $ $ $ $ $
$ $ $ $$$$$ $ $ $
$ $ $ $ $ $ $
$ $ $$$ $ $$$ $ $
$ $ $ $ $ $
$ $$$ $$$$$ $$$ $
$ $ $ $
$$$ $$$$$$$$$ $$$
$ $
$$$$$$$$$$$$$
对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数。
为了能准确比对空白的数量,程序要求对行中的空白以句点(.)代替。
输入格式:
一个正整数 n (n<30) 表示要求打印图形的层数
输出:
对应包围层数的该标志。
例如:
用户输入:
1
程序应该输出:
..$$$$$..
..$...$..
$$$.$.$$$
$...$...$
$.$$$$$.$
$...$...$
$$$.$.$$$
..$...$..
..$$$$$..
再例如:
用户输入:
3
程序应该输出:
..$$$$$$$$$$$$$..
..$...........$..
$$$.$$$$$$$$$.$$$
$...$.......$...$
$.$$$.$$$$$.$$$.$
$.$...$...$...$.$
$.$.$$$.$.$$$.$.$
$.$.$...$...$.$.$
$.$.$.$$$$$.$.$.$
$.$.$...$...$.$.$
$.$.$$$.$.$$$.$.$
$.$...$...$...$.$
$.$$$.$$$$$.$$$.$
$...$.......$...$
$$$.$$$$$$$$$.$$$
..$...........$..
..$$$$$$$$$$$$$..
请仔细观察样例,尤其要注意句点的数量和输出位置。
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
细节处理,注意30层的规模至少要125的大小。处理一下四个转弯,四个直线,然后四个正方形(都是白色部分)
#include <bits/stdc++.h>
using namespace std;
int img[126][126];
void bian (int k, int x, int y) { //处理四条边
int dist = 4*k-2; //各个点之间的距离
int len = 4*k-3; //各条边之间的长度
int nxt[4][2];
nxt[0][0] = x - 2; nxt[0][1] = y;
nxt[1][0] = x; nxt[1][1] = y - 2;
nxt[2][0] = x + dist + 2; nxt[2][1] = y + dist;
nxt[3][0] = x + dist; nxt[3][1] = y + dist + 2;
for (int i = 1; i <= len; i++) {
img[nxt[0][0]][nxt[0][1]+i] = 1;
img[nxt[1][0]+i][nxt[1][1]] = 1;
img[nxt[2][0]][nxt[2][1]-i] = 1;
img[nxt[3][0]-i][nxt[3][1]] = 1;
}
}
void jiao (int k, int x, int y) { //处理四个角
int dist = 4*k-2; //各个点的距离
int nxt[4][2];
nxt[0][0] = x; nxt[0][1] = y;
nxt[1][0] = x + dist; nxt[1][1] = y;
nxt[2][0] = x; nxt[2][1] = y + dist;
nxt[3][0] = x + dist; nxt[3][1] = y + dist;
for (int i = 0; i < 3; i++) {
img[nxt[0][0]-i][nxt[0][1]] = 1;
img[nxt[0][0]][nxt[0][1]-i] = 1;
img[nxt[1][0]+i][nxt[1][1]] = 1;
img[nxt[1][0]][nxt[1][1]-i] = 1;
img[nxt[2][0]-i][nxt[2][1]] = 1;
img[nxt[2][0]][nxt[2][1]+i] = 1;
img[nxt[3][0]+i][nxt[3][1]] = 1;
img[nxt[3][0]][nxt[3][1]+i] = 1;
}
}
void Solution (int n, int k) {
int x,y;
x = 4; y = 4;
memset(img, 0, sizeof(img));
img[1][1] = 1;
img[1][2] = 1;
img[2][1] = 1;
img[2][2] = 1;
img[k][1] = 1;
img[k][2] = 1;
img[k-1][1] = 1;
img[k-1][2] = 1;
img[1][k] = 1;
img[1][k-1] = 1;
img[2][k] = 1;
img[2][k-1] = 1;
img[k][k] = 1;
img[k][k-1] = 1;
img[k-1][k] = 1;
img[k-1][k-1] = 1;
for (int i = n; i >= 1; i--) {
jiao(i, x, y);
bian(i, x, y);
x += 2;
y += 2;
}
}
int main() {
int n,guimo;
cin >> n;
guimo = 4*n+5;
Solution(n, guimo);
for (int i = 1; i <= guimo; i++) {
for (int j = 1; j <= guimo; j++) {
if (img[i][j] == 1) {
printf(".");
}else {
printf("$");
}
}
printf("\n");
}
return 0;
}
标题:带分数
100 可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
题目要求:
从标准输入读入一个正整数N (N<1000*1000)
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
例如:
用户输入:
100
程序输出:
11
再例如:
用户输入:
105
程序输出:
6
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
搜索+剪枝
#include <bits/stdc++.h>
using namespace std;
int N;
int val[10];
int ToInteger(int l, int r) {
int res = 0;
for (int i = l; i < r; i++) {
res = res*10 + val[i];
}
return res;
}
int DFS (int idx) {
if (idx == 9) {
int cnt = 0;
int A,B,C,goal;
for (int i = 1; i < 9; i++) {
goal = N;
A = ToInteger(0, i);
if (A > N) {
break;
}
goal -= A;
for (int j = i + ((9 - i) >> 1); j < 9; j++) {
B = ToInteger(i, j);
C = ToInteger(j, 9);
if (B == C*goal) {
cnt++;
}else if (C*goal < B) {
break;
}
}
}
return cnt;
}
int ans = 0;
for (int i = idx; i < 9; i++) {
swap(val[i], val[idx]);
ans += DFS(idx + 1);
swap(val[i], val[idx]);
}
return ans;
}
int main() {
for (int i = 0; i < 9; i++) {
val[i] = i + 1;
}
cin >> N;
cout << DFS(0) << endl;
return 0;
}
标题:剪格子
如图p1.jpg所示,3 x 3 的格子中填写了一些整数。
我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0
程序输入输出格式要求:
程序先读入两个整数 m n 用空格分割 (m,n<10)
表示表格的宽度和高度
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000
程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。
例如:
用户输入:
3 3
10 1 52
20 30 1
1 2 3
则程序输出:
3
再例如:
用户输入:
4 3
1 1 1 1
1 30 80 2
1 1 1 100
则程序输出:
10
(参见p2.jpg)
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 5000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
图的深搜+剪枝
#include <bits/stdc++.h>
using namespace std;
const int maxn = (int)1e1+5;
const int INF = 0x3f3f3f3f;
typedef long long LL;
int img[maxn][maxn],vis[maxn][maxn],n,m,res;
int nxt[4][2] = {0,1,1,0,0,-1,-1,0};
LL goal;
void DFS (int x, int y, int cnt, LL sum) {
if (sum > goal) {
return ;
}
if (sum == goal) {
res = min(res, cnt);
return ;
}
int nx,ny;
for (int i = 0; i < 4; i++) {
nx = x + nxt[i][0];
ny = y + nxt[i][1];
if (nx < 1 || nx > n || ny < 1 || ny > m || vis[nx][ny] == 1) {
continue;
}
vis[nx][ny] = 1;
DFS (nx, ny, cnt + 1, sum + img[nx][ny]);
vis[nx][ny] = 0;
}
}
int main() {
goal = 0;
cin >> m >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> img[i][j];
goal += img[i][j];
}
}
if (goal % 2 ==0 && goal/2 > img[1][1]) {
goal /= 2;
res = INF;
memset(vis, 0, sizeof(vis));
vis[1][1] = 1;
DFS(1, 1, 1, img[1][1]);
if (res != INF) {
cout << res << endl;
}else {
cout << 0 << endl;
}
}else {
cout << 0 << endl;
}
return 0;
}