题目 | 类型 |
---|---|
网友年龄 | 结果填空 |
生日蜡烛 | 结果填空 |
方格填数 | 结果填空 |
快速排序 | 代码填空 |
消除尾一 | 代码填空 |
寒假作业 | 结果填空 |
剪邮票 | 结果填空 |
四平方和 | 程序设计 |
密码脱落 | 程序设计 |
最大比例 | 程序设计 |
1. 网友年龄
-
本题总分:3分
-
问题描述
某君新认识一网友。
当问及年龄时,他的网友说:
“我的年龄是个2位数,我比儿子大27岁,
如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄”请你计算:网友的年龄一共有多少种可能情况?
提示:30岁就是其中一种可能哦.
请填写表示可能情况的种数。
-
注意
你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
-
解析
#include<iostream> using namespace std; int main() { int ans = 0; for (int dad = 27; dad <= 99; dad++) { int son = dad % 10 * 10 + dad / 10; if (dad - son == 27) ans++; } cout << ans; return 0; }
-
答案
7
2. 生日蜡烛
-
本题总分:5分
-
问题描述
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。
现在算起来,他一共吹熄了236根蜡烛。
请问,他从多少岁开始过生日party的?
请填写他开始过生日party的年龄数。
-
注意
你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
-
解析
#include<iostream> using namespace std; int main() { bool find = false; for (int i = 1; i <= 100; i++) { int sum = 0; for (int j = i; j <= 100; j++) { sum += j; if (sum == 236) { cout << i; find = true; break; } } if (find) break; } return 0; }
-
答案
26
3. 方格填数
-
本题总分:11分
-
问题描述
如下的10个格子
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)一共有多少种可能的填数方案?
请填写表示方案数目的整数。
-
注意
你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
-
解析
#include<iostream> using namespace std; int map[6][6]; int ans; bool vis[10]; bool check(int x, int y, int n) { if (vis[n]) return false; if (x < 1 || x > 3) return false; if (y < 1 || y > 4) return false; if (map[x][y] != 0) return false; if (abs(map[x][y - 1] - n) <= 1) return false; if (abs(map[x - 1][y] - n) <= 1) return false; if (abs(map[x - 1][y - 1] - n) <= 1) return false; if (abs(map[x - 1][y + 1] - n) <= 1) return false; return true; } void dfs(int x, int y) { //遍历数字 for (int i = 0; i <= 9; i++) { int x0, y0; //如果到了最后一列 if (y == 4) { x0 = x + 1; y0 = 1; } //一般情况 else { x0 = x; y0 = y + 1; } //到达最后一个格 if (x0 == 3 && y0 == 4) { ans++; return; } //满足条件,进行深搜 if (check(x0, y0, i)) { map[x0][y0] = i; vis[i] = true; dfs(x0, y0); map[x0][y0] = 0; vis[i] = false; } } } int main() { //初始化地图 memset(map, 10, sizeof(map)); //3*4的地图 for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 4; j++) { map[i][j] = 0; } } //左上角和右下角的方格 map[1][1] = -2; map[3][4] = -2; dfs(1, 1); cout << ans; return 0; }
-
答案
1580
4. 快速排序
-
本题总分:9分
-
问题描述
排序在各种场合经常被用到。
快速排序是十分常用的高效率的算法。其思想是:先选一个“标尺”,
用它把整个队列过一遍筛子,
以保证:其左边的元素都不大于它,其右边的元素都不小于它。这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。下面的代码是一种实现,请分析并填写划线部分缺少的代码。
#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); } ______________________; 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; }
-
注意
只填写缺少的内容,不要书写任何题面已有代码或说明性文字。
-
答案
swap(a, p, j); //将最初的基准值与之后返回的下标对应的数据进行交换
5. 消除尾一
-
本题总分:13分
-
问题描述
下面的代码把一个整数的二进制表示的最右边的连续的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 = _______________________; for(i=0; i<32; i++) printf("%d", (x>>(31-i))&1); printf("\n"); } int main() { f(103); f(12); return 0; }
-
注意
只填写缺少的内容,不要书写任何题面已有代码或说明性文字。
-
答案
x & (x + 1)
6. 寒假作业
-
本题总分:15分
-
问题描述
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:每个方块代表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<iostream> using namespace std; int a[5][3]; bool vis[14]; int ans; bool check(int x, int y, int n) { if (a[x][y] != 0) return false;//该点已遍历过 if (vis[n]) return false;//该数字已使用过 if (x < 1 || x > 4) return false;//越界 if (y < 1 || y > 2) return false;//越界 if (x == 1 && y == 2) { if ((a[x][1] + n) < 1 || (a[x][1] + n) > 13) return false;//结果越界 if (a[x][1] + n == a[x][1] || a[x][1] + n == n) return false;//结果与前2个数之一相等 if (vis[a[x][1] + n]) return false;//结果的数字已使用过 } if (x == 2 && y == 2) { if ((a[x][1] - n) < 1 || (a[x][1] - n) > 13) return false;//结果越界 if (a[x][1] - n == a[x][1] || a[x][1] - n == n) return false;//结果与前2个数之一相等 if (vis[a[x][1] - n]) return false;//结果的数字已使用过 } if (x == 3 && y == 2) { if ((a[x][1] * n) < 1 || (a[x][1] * n) > 13) return false;//结果越界 if (a[x][1] * n == a[x][1] || a[x][1] * n == n) return false;//结果与前2个数之一相等 if (vis[a[x][1] * n]) return false;//结果的数字已使用过 } if (x == 4 && y == 2) { if (a[x][1] % n != 0) return false;//不能被整除 if ((a[x][1] / n) < 1 || (a[x][1] / n) > 13) return false;//结果越界 if (a[x][1] / n == a[x][1] || a[x][1] / n == n) return false;//结果与前2个数之一相等 if (vis[a[x][1] / n]) return false;//结果的数字已使用过 } return true; } void sign(int x, int y, bool sign) { //标记结果的数字 if (x == 1 && y == 2) vis[a[x][1] + a[x][2]] = sign; else if (x == 2 && y == 2) vis[a[x][1] - a[x][2]] = sign; else if (x == 3 && y == 2) vis[a[x][1] * a[x][2]] = sign; else if (x == 4 && y == 2) vis[a[x][1] / a[x][2]] = sign; } void dfs(int x, int y) { //如果已使用了12个数字,说明已完成一次遍历。ans++ int sum = 0; for (int i = 1; i <= 13; i++) { if (vis[i]) sum++; } if (sum == 12) { ans++; return; } for (int i = 1; i <= 13; i++) { int x0, y0; if (y == 2) { x0 = x + 1; y0 = 1; } else { x0 = x; y0 = y + 1; } if (check(x0, y0, i)) { a[x0][y0] = i; vis[i] = true; sign(x0, y0, true); dfs(x0, y0); vis[i] = false; sign(x0, y0, false); a[x0][y0] = 0; } } } int main() { dfs(1, 0); cout << ans; return 0; }
-
答案
64
7. 剪邮票
-
本题总分:19分
-
问题描述
如图,有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)比如,下两图中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
-
注意
你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
-
解析
#include<iostream> #include<algorithm> using namespace std; char a[4][5]; //用于存放1-12 bool vis[4][5]; string Sfind[1005]; //用于存放已找到的裁剪方式 string s_black; //空字符串 int ans; //答案 int cnt; //Sfind数组计数 int dx[4] = { 0, 0, 1, -1 }; int dy[4] = { 1, -1, 0, 0 }; //检查下一步的正确性 bool check(int x, int y) { if (vis[x][y]) return false; if (x < 1 || x > 3) return false; if (y < 1 || y > 4) return false; return true; } //检查记录的s是否已到达5个,并且和之前的没有重复 bool check_s(string s) { sort(s.begin(), s.end());//排序s,便于对比 if (s.length() != 5) return false; if (s.length() == 5) { for (int i = 0; i < 1005; i++) { if (Sfind[i] == s) return false; } } Sfind[cnt++] = s; return true; } void dfs(int x, int y, string s) { if (check_s(s)) { ans++; return; } for (int i = 0; i < 4; i++) { int x0 = x + dx[i]; int y0 = y + dy[i]; if (check(x0, y0)) { vis[x0][y0] = 1; dfs(x0, y0, s + a[x0][y0]); vis[x0][y0] = 0; } } } int main() { //初始化1-12,而使用str记录,因此用char初始化 char c = 'a'; for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 4; j++) { a[i][j] = c++; } } //每个点都作为开头进行遍历 for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 4; j++) { memset(vis, 0, sizeof(vis)); vis[i][j] = 1; dfs(i, j, s_black + a[i][j]); } } cout << ans; return 0; }
-
答案
82
8. 四平方和
-
本题总分:21分
-
问题描述
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。比如:
5 = 02 + 02 + 12 + 22
7 = 12 + 12 + 12 + 22对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对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 -
注意
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
main函数需要返回0
只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
-
答案
#include<iostream> using namespace std; int main() { int n; cin >> n; bool flag = false; for (int i = 0; i < 2306; i++) { if (flag) break; for (int j = i; j < 2306; j++) { if (flag) break; for (int k = j; k < 2306; k++) { if (flag) break; for (int l = k; l < 2306; l++) { int t = i * i + j * j + k * k + l * l; if (t == n) { cout << i << " " << j << " " << k << " " << l << endl; flag = true; break; } } } } } return 0; }
9. 密码脱落
-
本题总分:25分
-
问题描述
X星球的考古学家发现了一批古代留下来的密码。
这些密码是由A、B、C、D 四种植物的种子串成的序列。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。你的任务是:
给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。 -
输入格式
输入一行,表示现在看到的密码串(长度不大于1000)
-
输出格式
要求输出一个正整数,表示至少脱落了多少个种子。
-
样例输入
ABCBA
-
样例输出
0
-
样例输入
ABDCDCBABC
-
样例输出
3
-
资源约定
峰值内存消耗 < 256M
CPU消耗 < 1000ms -
注意
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
main函数需要返回0
只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
-
答案
#include<iostream> using namespace std; string s; int ans = 0x3f3f3f; void dfs(int l, int r, int len) { if (l >= r) { if (ans > len) ans = len; return; } //相等 if (s[l] == s[r]) dfs(l + 1, r - 1, len); //不相等 else { dfs(l + 1, r, len + 1); dfs(l, r - 1, len + 1); } } int main() { cin >> s; dfs(0, s.length() - 1, 0); cout << ans; return 0; }
10. 最大比例
-
本题总分:29分
-
问题描述
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 -
注意
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
main函数需要返回0
只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
-
答案
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> int N; long long bonus[100]; long long res[100], p1[100], p2[100]; long long num1, num2; void sort() { long long tmp; for(int i=0;i<N;i++) { for(int j=i+1;j<N;j++) { if( bonus[j] < bonus[i] ) { tmp = bonus[j]; bonus[j] = bonus[i]; bonus[i] = tmp; } } } } void removeSame() { int k = 1; res[0] = bonus[0]; for(int i=1;i<N;i++) { if( bonus[i] == bonus[i-1] ) continue; res[k++] = bonus[i]; } N = k; } long long gcd(long long a, long long b) { long long t; if( b == 0 ) return a; else return gcd( b, a%b ); } long long max(long long a, long long b) { return a >= b ? a : b; } long long min(long long a, long long b) { return a <= b ? a : b; } void solve() { int tmp; int k; if( N == 1 ) { num1 = 1; num2 = 1; return; } else if( N == 2 ) { tmp = gcd( res[1], res[0] ); num1 = res[1] / tmp; num2 = res[0] / tmp; return; } else { k = 0; long long g,g1,g2; for(int i=1;i<N;i++) { tmp = gcd( res[i], res[i-1] ); p1[k] = res[i] / tmp; p2[k] = res[i-1] / tmp; k++; } } double t = 999999; // 存储最小的公约数 long long t1, t2, tt1, tt2, max_tmp, min_tmp; long long max_p1, max_p2, min_p1, min_p2; for(int i=0;i<N-1;i++) { for(int j=i+1;j<N-1;j++) { if( p1[i]*p2[j] == p1[j]*p2[i] ) { t1 = p1[i]; t2 = p2[i]; } else { max_p1 = max( p1[i], p1[j] ); max_p2 = max( p2[i], p2[j] ); min_p1 = min( p1[i], p1[j] ); min_p2 = min( p2[i], p2[j] ); max_tmp = max_p1; min_tmp = min_p1; max_p1 = max( min_tmp, max_tmp/min_tmp ); min_p1 = min( min_tmp, max_tmp/min_tmp ); max_tmp = max_p2; min_tmp = min_p2; max_p2 = max( min_tmp, max_tmp/min_tmp ); min_p2 = min( min_tmp, max_tmp/min_tmp ); t1 = gcd( max_p1, min_p1 ); t2 = gcd( max_p2, min_p2 ); } // 在之前的程序中可知p1>p2 if( 1.0*t1/t2 < t ) { t = 1.0*t1/t2; tt1 = t1; tt2 = t2; } } } tmp = gcd(tt1, tt2); num1 = tt1 / tmp; num2 = tt2 / tmp; } int main() { scanf("%d", &N); for(int i=0;i<N;i++) scanf("%lld", &bonus[i]); sort(); removeSame(); solve(); printf("%lld/%lld\n", num1, num2); return 0; }
引用:https://blog.csdn.net/u012526003/article/details/79460697