本文共 4477 字,大约阅读时间需要 14 分钟。
注:其他题目与A组题目相同,题解在我的A组题解中,
题目 | 类型 | 分值 |
---|---|---|
第一题 | 结果填空 | 3分 |
第二题 | 结果填空 | 5分 |
第三题 | 结果填空 | 11分 |
第四题 | 代码填空 | 9分 |
第五题 | 代码填空 | 13分 |
第六题 | 结果填空 | 15分 |
第七题 | 结果填空 | 19分 |
第八题 | 程序设计 | 21分 |
第九题 | 程序设计 | 23分 |
第十题 | 程序设计 | 31分 |
问题重现
有一堆煤球,堆成三角棱锥形。具体:
第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形), … 如果一共有100层,共有多少个煤球?请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
解题思路、
易知 a i − a i − 1 = i a_i-a_{i-1}=i ai−ai−1=i,我们累加即可。
代码
/*** @filename:煤球数目.cbp* @Author : pursuit* @Blog:unique_pursuit* @email: 2825841950@qq.com* @Date : 2021-03-18-21.28.26*/#includeusing namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;const int maxn=1e5+5;const int mod=1e9+7;//易知ai-a(i-1)=i。累加即可。我们认为第0层为0。//171700void solve(){ int temp=0,ans=0; for(int i=1;i<=100;i++){ temp+=i; ans+=temp; cout< <<" "; } cout< <
答案
171700 171700 171700.
问题重现
A + C B + D E F G H I = 10 A+\frac{C}B+\frac{DEF}{GHI}=10 A+BC+GHIDEF=10
这个算式中A~I代表1->9的数字,不同的字母代表不同的数字。
比如:
6 + 8 / 3 + 952 / 714 6+8/3+952/714 6+8/3+952/714 就是一种解法, 5 + 3 / 1 + 972 / 486 5+3/1+972/486 5+3/1+972/486 是另一种解法。这个算式一共有多少种解法?
注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
解题思路
暴力全排列或者 d f s dfs dfs都可以处理,要注意的就是我们怎么处理这个算式,绝对不能直接计算,需要同分再移位,把除号给去掉。
代码
/*** @filename:凑算式.cbp* @Author : pursuit* @Blog:unique_pursuit* @email: 2825841950@qq.com* @Date : 2021-03-18-21.39.51*/#includeusing namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;const int maxn=1e5+5;const int mod=1e9+7;//dfs或暴力全排列。bool vis[10];//vis[i]表示i是否被选择。int a[10];//a[1]->a[9]对应ABCDEFGHI。int ans=0;void dfs(int step){ //step表示当前正在填第几个数。 if(step==10){ //说明前9个数已经填完了,我们判断。注意不要掉入题目的坑,利用通分之后的式子进行运算。 int temp1=a[7]*100+a[8]*10+a[9],temp2=a[4]*100+a[5]*10+a[6]; if(a[1]*a[3]*temp2+a[2]*temp2+a[3]*temp1==10*a[3]*temp2){ ans++; } return; } for(int i=1;i<10;i++){ if(!vis[i]){ vis[i]=true; a[step]=i; dfs(step+1); vis[i]=false; } }}void solve(){ dfs(1); cout< <
答案
29 29 29.
问题重现
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#define N 6#define M 5#define BUF 1024void 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 仔细阅读代码,填写划线部分缺少的内容。
注意:不要填写任何已有内容或说明性文字。
解题思路
解决这种类型的题目我们首先要知道程序的作用。输出所有的派出组合。那么这个 f f f函数即是实现这个功能的,对于数组 a a a,其中 a [ i ] a[i] a[i]就代表了 ′ A ′ + i 'A'+i ′A′+i国最多能派出多少人,那么 b b b即是存储组合的字符串,作为输出。很明显,这是一个递归函数,其中的 k k k在递归开始为 0 0 0,在退出的时候 k = N k=N k=N,这个 k k k代表的就是我们当前正在选的国家,而 M M M即是剩余安排的人数。最核心的就是这两个 f o r for for循环,我们发现在第二个 f o r for for循环下,不断给数组 b b b赋值,赋值了 i i i个,那么这也说明,这里被选了 i i i个,那么接下来那一行其实我们就应该知道怎么填了,更改剩余人数和所填国家即可。
答案
f(a,k+1,m-i,b)
问题重现
有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
解题思路
这道题不用想的太复杂,我们最终是要将下标与其值相等。那么倘若我们存储了一开始值的下标,那么我就知道了 i i i它所在的位置。这里用 v a l val val数组表示值, p o s pos pos数组表示位置,那么我们就可以直接遍历数组判断 v a l [ i ] = = i val[i]==i val[i]==i,如果不等于,我们就可以找到 i i i它在哪个位置,我们交换这两个位置的值即可。(交换之后记得更新 p o s pos pos)这样就保证了我们遍历的时候能将位置不对的一步就能转换。利用这样的操作,我们就能求出最少操作次数。
代码
/*** @filename:交换瓶子.cbp* @Author : pursuit* @Blog:unique_pursuit* @email: 2825841950@qq.com* @Date : 2021-03-20-19.35.50*/#includeusing namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;const int maxn=1e5+5;const int mod=1e9+7;int n,val[maxn],pos[maxn];void Swap(int a,int b){ int temp=val[a]; val[a]=val[b]; val[b]=temp;}void solve(){ int ans=0; for(int i=1;i<=n;i++){ if(val[i]!=i){ //我们就要将是1的换到这里来。 int temp1=pos[i];//我们知道i的位置。 int temp2=val[i]; Swap(i,pos[i]);//将真正的i的位置换过去。 pos[temp2]=temp1; ans++; } } cout< < >n){ for(int i=1;i<=n;i++){ cin>>val[i]; pos[val[i]]=i;//存储这个值的位置。 } solve(); } return 0;}
转载地址:http://vcsn.baihongyu.com/