1.题目标题: 猜年龄
美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。
一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,他回答说:
“我年龄的立方是个4位数。我年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”
请你推算一下,他当时到底有多年轻。
通过浏览器,直接提交他那时的年龄数字。
注意:不要提交解答过程,或其它的说明文字。
思路:通过位数大致确定范围,打印计算结果观察
答案:18
//10^3=1000 10^4=10000
//30^3=27000 30^4=810000
#include
#include
#include
using namespace std;
int main(){
for(int i=10;i<=30;i++)
cout<
2. 题目标题: 排它平方数
小明正看着 203879 这个数字发呆。
原来,203879 * 203879 = 41566646641
这有什么神奇呢?仔细观察,203879 是个6位数,并且它的每个数位上的数字都是不同的,并且它平方后的所有数位上都不出现组成它自身的数字。
具有这样特点的6位数还有一个,请你找出它!
再归纳一下筛选要求:
1. 6位正整数
2. 每个数位上的数字不同
3. 其平方数的每个数位不含原数字的任何组成数位
答案是一个6位的正整数。
请通过浏览器提交答案。
注意:只提交另一6位数,题中已经给出的这个不要提交。
注意:不要书写其它的内容(比如:说明性的文字)。
#include
#include
#include
using namespace std;
int i,j,k,a,b,c;
bool have(int x){
if(x==i||x==j||x==k||x==a||x==b||x==c) return true;
return false;
}
bool judge(){
long long n=i*100000+j*10000+k*1000+a*100+b*10+c;
long long m=n*n;
while(m){
int tmp=m%10;
if(have(tmp)) return false;
m/=10;
}
return true;
}
int main(){
int n;
for( i=1;i<=9;i++)
for( j=0;j<=9;j++)
for( k=0;k<=9;k++)
for( a=0;a<=9;a++)
for( b=0;b<=9;b++)
for( c=0;c<=9;c++)
if(i!=j&&i!=k&&i!=a&&i!=b&&i!=c&&j!=k&&j!=a&&j!=b&&j!=c&&k!=a&&k!=b&&k!=c&&a!=b&&a!=c&&b!=c)
if(judge()) cout<
#include
#include
#define ll long long
using namespace std;
int vis[10];
int is[10];
bool judge(int x) {
int xx=x;
while(xx) {
vis[xx%10]++;
xx/=10;
}
for(int i=0; i<=9; i++)
if(vis[i]>1) return false;
return true;
}
bool check(ll x) {
ll xx=x*x;
while(xx) {
is[xx%10]++;
xx/=10;
}
for(int i=0; i<=9; i++)
if(vis[i]!=0&&is[i]!=0) return false;
return true;
}
int main() {
for(int i=100000; i<999999; i++) {
memset(vis,0,sizeof vis);
memset(is,0,sizeof is);
if(!judge(i)) continue;
if(check(i)) cout<
3. 标题: 振兴中华
小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:(也可参见p1.jpg)
从我做起振
我做起振兴
做起振兴中
起振兴中华
比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。
要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
答案是一个整数,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。
这道题手工算的,答案是35
这是深搜代码:
#include
#include
#include
#define ll long long
using namespace std;
//int mp[4][5]=//只要向右和向下走就都符合题意故不用mp也不影响
int cnt=0;
int vis[4][5];
int mov[2][2]={0,1,1,0};
void dfs(int x,int y){
if(x==3&&y==4) cnt++; //递归出口:到达终点即成功
for(int i=0;i<2;i++){//只有向右和向下两个方向
int nx=x+mov[i][0];
int ny=y+mov[i][1];
if(nx<0||nx>3||ny<0||ny>4) continue;
vis[nx][ny]=1;
dfs(nx,ny);
vis[nx][ny]=0;
}
}
int main() {
vis[0][0]=1;
dfs(0,0);//从起点开始
cout<
4.标题: 幻方填空
幻方是把一些数字填写在方阵中,使得行、列、两条对角线的数字之和都相等。
欧洲最著名的幻方是德国数学家、画家迪勒创作的版画《忧郁》中给出的一个4阶幻方。
他把1,2,3,...16 这16个数字填写在4 x 4的方格中。
如图p1.jpg所示,即:
16 ? ? 13
? ? 11 ?
9 ? ? *
? 15 ? 1
表中有些数字已经显露出来,还有些用?和*代替。
请你计算出? 和 * 所代表的数字。并把 * 所代表的数字作为本题答案提交。
答案是一个整数,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。
#include
#include
#include
using namespace std;
int a[10]={2,3,4,5,6,7,8,10,12,14};
int sum[10];
int main(){
do{
sum[0]=16+a[0]+a[1]+13; //横四行
sum[1]=11+a[2]+a[3]+a[4];
sum[2]=9+a[5]+a[6]+a[7];
sum[3]=15+1+a[8]+a[9];
sum[4]=16+9+a[2]+a[8]; //纵四行
sum[5]=15+a[0]+a[3]+a[5];
sum[6]=11+a[1]+a[6]+a[9];
sum[7]=13+1+a[4]+a[7];
sum[8]=16+1+a[3]+a[6]; //两条对角线
sum[9]=13+11+a[5]+a[8];
int n=9,flag=0;
for(int i=1;i<=9;i++){
if(sum[i]!=sum[0]){
flag=1;
break;
}
}
if(flag==0) break;
}while(next_permutation(a,a+10));
cout<
5.题目标题:公约数公倍数
我们经常会用到求两个整数的最大公约数和最小公倍数的功能。
下面的程序给出了一种算法。
函数 myfunc 接受两个正整数a,b
经过运算后打印出 它们的最大公约数和最小公倍数。
此时,调用 myfunc(15,20)
将会输出:
3
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 m=a;n=b;r=a%b;
while(r!=0)
{
a=b;b=r;
r=a%b;
}
printf("%d\n",b); // 最大公约数
printf("%d\n", ____________________________________); // 最小公倍数
}
请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!
m*n/b
6.标题:逆波兰表达式
正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便。
例如:3 + 5 * (2 + 6) - 1
而且,常常需要用括号来改变运算次序。
相反,如果使用逆波兰表达式(前缀表达式)表示,上面的算式则表示为:
- + 3 * 5 + 2 6 1
不再需要括号,机器可以用递归的方法很方便地求解。
为了简便,我们假设:
1. 只有 + - * 三种运算符
2. 每个运算数都是一个小于10的非负整数
下面的程序对一个逆波兰表示串进行求值。
其返回值为一个结构:其中第一元素表示求值结果,第二个元素表示它已解析的字符数。struct EV
{
int result; //计算结果
int n; //消耗掉的字符数
};struct EV evaluate(char* x)
{
struct EV ev = {0,0};
struct EV v1;
struct EV v2;if(*x==0) return ev;
if(x[0]>='0' && x[0]<='9'){
ev.result = x[0]-'0';
ev.n = 1;
return ev;
}
v1 = evaluate(x+1);
v2 = _____________________________; //填空位置
if(x[0]=='+') ev.result = v1.result + v2.result;
if(x[0]=='*') ev.result = v1.result * v2.result;
if(x[0]=='-') ev.result = v1.result - v2.result;
ev.n = 1+v1.n+v2.n;return ev;
}请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!
看规律——空与递归有关,根据规律猜测,然后写程序测试
struct EV
{
int result; //计算结果
int n; //消耗掉的字符数
};
struct EV evaluate(char* x)
{
struct EV ev = {0,0};
struct EV v1;
struct EV v2;
if(*x==0) return ev;
if(x[0]>='0' && x[0]<='9'){
ev.result = x[0]-'0';
ev.n = 1;
return ev;
}
v1 = evaluate(x+1);
v2 = evaluate(x+v1.n+1); //填空位置
if(x[0]=='+') ev.result = v1.result + v2.result;
if(x[0]=='*') ev.result = v1.result * v2.result;
if(x[0]=='-') ev.result = v1.result - v2.result;
ev.n = 1+v1.n+v2.n;
return ev;
}
# include
int main()
{
char a[]={"-+3*5+261"};
EV ev2=evaluate(a);
printf("%d\n",ev2.result);
}
7.标题:核桃的数量
小张是软件项目经理,他带领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, 不能通过工程设置而省略常用头文件。 提交时,注意选择所期望的编译器类型。
思路:求三个数的最小公倍数
#include
#include
#include
#include
using namespace std;
int gcd(int a,int b){
int aa=a,bb=b,r;
while(b){
r=a%b;
a=b;
b=r;
}
return aa*bb/a;
}
int main(){
int a,b,c;
cin>>a>>b>>c;
cout<
8.题目标题:打印十字图
小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示(可参见p1.jpg)样例输入2
3
样例输出2提示
请仔细观察样例,尤其要注意句点的数量和输出位置。
来自大佬的题解:(其实我是根据打印出的图形帮助理解的,并不特别透……)
#include
#include
//思路:先摆放左上角所有$图案,然后通过对称画出其他部分
//打印十字图
void Decphoto(int n)
{
int row = 0, col = 0, i = 0, j = 0, center = 0;
int space = 0, num_s = 0, t = 0;
row = col = 4*(n-1)+9; //n层时,数组大小
int **arr = (int **)malloc(sizeof(int *)*row);//开辟一维
for (i = 0; i < row; ++i) //动态开辟二维数组空间
arr[i] = (int *)malloc(sizeof(int)*col);
center = (row-1)/2; //数组最中部那点坐标
for (i = 0; i < row; ++i) //全部初始化为'.'
for (j = 0; j < col; ++j)
arr[i][j] = '.';
for (i = center-1; i <= center; ++i) //摆放中心十字图
{
arr[center][i] = '$';
arr[i][center] = '$';
}
space = center; //摆放$时,前面跳过个数space
t = num_s = 1; //需要连续摆放num_s个$
//(A区域),(C区域)
for (i = center-2; i >= 0; i -= 2) //摆放上面到中心和左边到中心'$'型
{ //这里从中心往外围摆放$
for (j = space; t > 0; ++j)
{
arr[i][j] = '$';
arr[j][i] = '$';
--t;
}
space -= 2; //注意观察规律
t = num_s += 2;
}
//(B区域)
for (i = 1; i < center-1; i += 2) //摆放中上对角线
arr[i][i+1] = '$';
for (i = 2; i < center; i += 2) //摆放正对角线
arr[i][i] = '$';
for (i = 2; i < center-1; i += 2) //摆放中下对角线
arr[i][i-1] = '$';
//至此,左上角的图案全部摆放完毕(然后通过对称性...)
//(对称性 对折图形)
for (i = 0; i < (row+1)/2; ++i) //沿对角线对折
for (j = 0; j < (col+1)/2; ++j)
arr[row-i-1][col-j-1] = arr[i][j];
for (i = 0; i < (row+1)/2; ++i) //沿列中线对折
for (j = 0; j < (col+1)/2; ++j)
arr[i][col-j-1] = arr[i][j];
for (i = 0; i < (row+1)/2; ++i) //沿行中线对折
for (j = 0; j < (col+1)/2; ++j)
arr[row-i-1][j] = arr[i][j];
for (i = 0; i < row; ++i) //打印十字图
{
for (j = 0; j < col; ++j)
printf("%c",arr[i][j]);
printf("\n");
}
return;
}
//主函数
int main()
{
int n = 0;
scanf("%d",&n);
Decphoto(n);
return 0;
}
官方解析:
9.标题:买不到的数目
小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。输入:
两个正整数,表示每种包装中糖的颗数(都不多于1000)要求输出:
一个正整数,表示最大不能买到的糖数例如:
用户输入:
4 7
程序应该输出:
17再例如:
用户输入:
3 5
程序应该输出:
7资源约定:
峰值内存消耗 < 64M
CPU消耗 < 3000ms请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include, 不能通过工程设置而省略常用头文件。 提交时,注意选择所期望的编译器类型。
“传说”有三种解法,在此取一种个人较好理解的做法,但是时间复杂度比较大
#include
#include
using namespace std;
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int main() {
int n,m;
cin>>n>>m;
if(gcd(n,m)==1) cout<
10.标题:剪格子
如图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, 不能通过工程设置而省略常用头文件。 提交时,注意选择所期望的编译器类型。
#include
#include
using namespace std;
int n,m,sum,minn=100;
int a[10][10];
int vis[10][10];
int mov[4][2]= {0,1,0,-1,1,0,-1,0};
void dfs(int x,int y,int pre_sum,int cnt) {//pre_sum为当前已经有的sum数,和已经剪掉的格子数
if(pre_sum==sum) {
if(cnt=n||ny<0||ny>=m||vis[nx][ny]) continue;
if(pre_sum+a[nx][ny]<=sum) { //检查是否可剪该格子
vis[nx][ny]=1;
dfs(nx,ny,pre_sum+a[nx][ny],cnt+1);
vis[nx][ny]=0;
}
}
}
int main() {
cin>>m>>n;
for(int i=0; i