1.A的个数
以下是一个 25 行 25 列的字母矩阵,全部由字母 A 和 B 组成。
AAAAAAABABBAABABABAAAAAAA
ABBBBBABBAABBBBBABABBBBBA
ABAAABABBBABAABBBBABAAABA
ABAAABABBBBBAABAABABAAABA
ABAAABABBABABBABABABAAABA
ABBBBBABBBABAABBBBABBBBBA
AAAAAAABABABABABABAAAAAAA
BBBBBBBBABAABABBBBBBBBBBB
AABAABABBAAABBAAABABBBBBA
ABBABABBBABBAAAABBBBAAAAB
BBBBAAABABAABABAABBBAABBA
BBAABABABAAAABBBAABBAAAAA
ABABBBABAABAABABABABBBBBA
AAAABBBBBABBBBAAABBBABBAB
AABAABAAABAAABAABABABAAAA
ABBBBBBBBABABBBBABAABBABA
ABBBAAABAAABBBAAAAAAABAAB
BBBBBBBBABBAAABAABBBABBAB
AAAAAAABBAAABBBBABABAABBA
ABBBBBABBAABABAAABBBABBAA
ABAAABABABBBAAAAAAAAAABAA
ABAAABABABABBBABBAABBABAA
ABAAABABBABBABABAABAABAAA
ABBBBBABABBBBBABBAAAABAAA
AAAAAAABAABBBAABABABBABBA
请问在这个矩阵中有多少个字母A? //318个
#include<iostream>
using namespace std;
//A的个数
string s[25]={
"AAAAAAABABBAABABABAAAAAAA",
"ABBBBBABBAABBBBBABABBBBBA",
"ABAAABABBBABAABBBBABAAABA",
"ABAAABABBBBBAABAABABAAABA",
"ABAAABABBABABBABABABAAABA",
"ABBBBBABBBABAABBBBABBBBBA",
"AAAAAAABABABABABABAAAAAAA",
"BBBBBBBBABAABABBBBBBBBBBB",
"AABAABABBAAABBAAABABBBBBA",
"ABBABABBBABBAAAABBBBAAAAB",
"BBBBAAABABAABABAABBBAABBA",
"BBAABABABAAAABBBAABBAAAAA",
"ABABBBABAABAABABABABBBBBA",
"AAAABBBBBABBBBAAABBBABBAB",
"AABAABAAABAAABAABABABAAAA",
"ABBBBBBBBABABBBBABAABBABA",
"ABBBAAABAAABBBAAAAAAABAAB",
"BBBBBBBBABBAAABAABBBABBAB",
"AAAAAAABBAAABBBBABABAABBA",
"ABBBBBABBAABABAAABBBABBAA",
"ABAAABABABBBAAAAAAAAAABAA",
"ABAAABABABABBBABBAABBABAA",
"ABAAABABBABBABABAABAABAAA",
"ABBBBBABABBBBBABBAAAABAAA",
"AAAAAAABAABBBAABABABBABBA"
};
int main()
{
int ans=0;
for(int i=0;i<25;i++){
for(int j=0;j<25;j++){
if(s[i][j]=='A') ans++;
}
}
cout<<ans<<endl;
return 0;
}
2.最2数字
如果一个整数的某个数位包含 2 ,则称这个数为一个“最2数字”。例如:102、2021 都是最2数字。
请问在 1(含) 到 2021(含) 中,有多少个最2数字。// 564
#include<iostream>
using namespace std;
//最2数字
bool check(int n){
while(n){
if(n%10==2) return true;
else n/=10;
}
return false;
}
int main()
{
int ans=0;
for(int i=1;i<=2021;i++)
if(check(i)) ans++;
cout<<ans<<endl;
return 0;
}
3.最少次数(贪心)
有一个整数 A=2021,每一次,可以将这个数加 1 、减 1 或除以 2,其中除以 2 必须在数是偶数的时候才允许。
例如,2021 经过一次操作可以变成 2020、2022。
再如,2022 经过一次操作可以变成 2021、2023 或 1011。
请问,2021 最少经过多少次操作可以变成 1。
贪心思想,能除2就除2,奇数就减1或加1如果是2的i次幂,就执行那个,否则就执行减1。
如果是填空题可以列举:
1)2020--> 2)1010--> 3)505--> 4)504--> 5)252--> 6)126--> 7)63--> 8)64--> 9)32--> 10)16--> 11)8
--> 12)4--> 13)2--> 14)1
当加1可以变成2的几次幂时,是最快的;否则,先减再除2;答案:最少14步
程序可以这样写:(但感觉没有直接想快)
#include<iostream>
using namespace std;
//最少次数
int main()
{
int ans=0,a[12],t=1;
for(int i=1;i<=12;i++){//2^11>2021,因此存储
t*=2;
a[i]=t;
}
int n=2021,f;
while(n!=1){
f=0;
for(int i=1;i<=12;i++){
if((n+1)==a[i]){
f=1;
break;
}
}
if(n%2==0) n/=2;
else if(f==1)n+=1;
else n-=1;
ans++;
}
cout<<ans<<endl;
return 0;
}
bfs求最短路径也可,但我不太会,so~
4.超大玉螺旋丸(模拟)
对于一个 n 行 m 列的表格,我们可以使用螺旋的方式给表格依次填上正整数,我们称填好的表格为一个螺旋矩阵。
例如,一个 4 行 5 列的螺旋矩阵如下:
1 2 3 4 5
14 15 16 17 6
13 20 19 18 7
12 11 10 9 8
请问,一个 30 行 30 列的螺旋矩阵,第 20 行第 20 列的值是多少?//819
#include <iostream>
using namespace std;
//螺旋矩阵
int a[30][30];
int main()
{
int num = 1;
int l=0, r=30-1, u=0, d=30-1;
while(num<=30*30){
for(int i=l;i<=r;i++) a[u][i]=num ++; // 向右
u++;
for (int i=u;i<=d;i++) a[i][r]=num ++; // 向下
r--;
for (int i=r;i>=l;i--) a[d][i]=num ++; // 向左
d--;
for (int i=d;i>=u;i--) a[i][l]=num ++; // 向上
l++;
}
cout << a[19][19] << endl;
return 0;
}
5.二叉树的最大深度
一棵二叉树有2021个结点。该树满足任意结点的左子树结点个数和右子树的结点个数之差最多为1(说明是完全二叉树)。定义根结点的深度为0,子结点的深度比父结点深度多1。
请问,树中深度最大的结点的深度最大可能是多少?
log2(2021)-1(根深度为1时),所以hmax=log2(2021)=10
6.和尚挑水
问题描述
一个和尚要挑水,每次最多能挑 a 千克,水缸最多能装 t 千克,开始时水缸为空。
请问这个和尚最少要挑多少次可以将水缸装满?
输入格式
输入一行包含两个整数 a, t,用一个空格分隔。
输出格式
输出一行包含一个整数,表示答案。
样例输入
20 2021
样例输出
102
评测用例规模与约定
对于所有评测用例,1 <= a <= 100,1 <= t <= 10000。
#include <iostream>
using namespace std;
//和尚挑水
int a,t,ans;
int main()
{
cin>>a>>t;
if(t%a==0) ans=t/a;//正好能整除
else ans=t/a+1;
cout<<ans<<endl;
return 0;
}
7.金融数字
问题描述
在金融领域,通常将金额的百位和千位之间、十万位和百万位之间增加逗号(千分位分隔符),以方便阅读。一般从个位开始,每三位之前增加一个逗号。
例如:1234567890.00 通常写成 1,234,567,890.00。
注意小数点后固定保留 2 位。
给定一个包含千分位分隔符的数值,请读入后输出对应的不含千分位的数值,小数点仍然保留 2 位。
输入格式
输入一行包含一个由千分位分隔符的数值,恰好有 2 位小数。
输出格式
输出不含千分位分隔符的数值,保留 2 位小数。
样例输入
1,234,567,890.00
样例输出
1234567890.00
评测用例规模与约定
对于所有评测用例,给定的数值整数部分不超过12位。
这也太太太水了趴~,,,,
#include <iostream>
using namespace std;
//金融数字
int main()
{
string s;
cin>>s;
for(int i=0;i<s.size();i++){
if(s[i]=='.') cout<<s[i];
else if(s[i]==',') continue;
else cout<<s[i]-'0';
}
return 0;
}
8.插座 (枚举)
问题描述
小蓝有一个插板,形状用一个 n * m 的0 1矩阵表示,0 表示板面,1 表示插孔。
小蓝还有一个插头,形状用一个 r * c 的0 1矩阵表示,0 表示没有伸出的部分,1 表示伸出的部分。插头伸出的部分必须插在插孔里面。
为了安全,插头插到面板上不能有任何部分超过插板边界(包括没有伸出的部分)。
插头和插板都不能旋转,也不能翻转。请求出插头插入插板的合理位置。
输入格式
输入的第一行包含两个整数 n, m。
接下来 n 行,每行一个长度为 m 的0 1串,表示插板的形状。
接下来一行包含两个整数 r, c。
接下来 r 行,每行一个长度为 c 的01串,表示插头的形状。
输出格式
如果插头没办法安全插入插板中,输出“NO”。否则输出两个数 a, b,表示插头的第 1 行第 1 列对应插板的第 a 行第 b 列。如果有多种情况满足要求,输出 a 最小的方案,如果 a 最小的方案有多个,输出在 a 最小的前提下 b 最小的方案。
样例输入
3 4
0110
0000
0000
3 3
000
010
000
样例输出
NO
样例说明
在插头不超出范围的前提下无法插入。
样例输入
4 7
1110100
1101111
0001111
0000011
2 3
111
011
样例输出
2 4
评测用例规模与约定
对于 50% 的评测用例,2 <= n, m, r, c <= 20。
对于所有评测用例,2 <= n, m, r, c <= 100。
如果插板的长或者宽小于插头,返回NO
#include <iostream>
using namespace std;
//插座
int r,c,n,m,a,b;
char s1[105][105],s2[105][105];//注意样例是连着的数字输入的,要用字符串处理
bool check(int x,int y){
for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
if(s2[i][j]=='1'&&s1[i+x][j+y]=='0') return false;
}
}
return true;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>s1[i][j];
cin>>r>>c;
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
cin>>s2[i][j];
if(n<r||m<c) cout<<"NO";
else{
for(int i=0;i+r-1<n;i++){//要保证插头最后一个不超过插板
for(int j=0;j+c-1<m;j++){
if(check(i,j)){
cout<<i+1<<" "<<j+1<<endl;//注意输出的是第几列第几行
return 0;
}
}
}
}
cout<<"NO"<<endl;
return 0;
}
9.公约数 (set的应用)
问题描述
给定正整数 a, b, c,请问有多少个正整数,是其中至少两个数的约数。
输入格式
输入一行包含三个正整数 a, b, c。
输出格式
输出一行包含一个整数,表示答案。
样例输入
30 70 35
样例输出
6
样例说明
1、2、5、7、10、35满足条件。
评测用例规模与约定
对于 50% 的评测用例,1 <= a, b, c <= 1000000。
对于所有评测用例,a, b, c 不超过 10^12(10的12次方)。
用set存储约数(直接去重),用set.count(i)返回集合中i的个数,判断两个集合中共同的约束
#include <iostream>
using namespace std;
//公约数
#include<set>
int a,b,c;
set<long long> s1,s2,ans;
int main()
{
cin>>a>>b>>c;
for(int i=1;i<=a/i;i++){
if(a%i==0){
s1.insert(i);
s1.insert(a/i);
}
}
for(int i=1;i<=b/i;i++){
if(b%i==0){
s2.insert(i);
s2.insert(b/i);
if(s1.count(i)) ans.insert(i);//如果s1中有,就保存在ans里
if(s1.count(b/i)) ans.insert(b/i);
}
}
for(int i=1;i<=c/i;i++){
if(c%i==0){
if(s1.count(i)||s2.count(i)) ans.insert(i);//s1或s2中有,就保存在ans里
if(s1.count(c/i)||s2.count(c/i)) ans.insert(c/i);
}
}
cout<<ans.size()<<endl;
return 0;
}
10.汉诺塔(求教)
问题描述
小蓝很喜欢玩汉诺塔游戏。
游戏中有三根柱子,开始时第一根柱子上有 n 个圆盘,从上到下圆盘的大小依次为 1 到 n。
每次,可以将一个盘子从一根柱子上移动到另一根柱子上,这个盘子必须是柱子最上方的盘子,而且移到的柱子上的盘子必须比这个盘子大。
小蓝的目标是将所有的盘子移动到第三根柱子上。
汉诺塔是个经典问题,当盘子数量为 n 时,最少需要移动 2^n-1 步。小蓝已经玩了一会儿(不一定按最优方案玩==>(则最少步数可能大于2^n-1)),他想知道,对于他目前的局面,最少还需要多少步可以到达目标。
输入格式
输入的第一行包含三个非负整数 a, b, c,分别表示目前每根柱子上的盘子数。在本题中,n=a+b+c。
第二行包含 a 个整数,相邻的整数之间使用一个空格分隔,表示第一根柱子上的盘子,盘子按从上到下(从小到大)的顺序给出。
第三行包含 b 个整数,相邻的整数之间使用一个空格分隔,表示第二根柱子上的盘子,盘子按从上到下(从小到大)的顺序给出。
第四行包含 c 个整数,相邻的整数之间使用一个空格分隔,表示第三根柱子上的盘子,盘子按从上到下(从小到大)的顺序给出。
输出格式
输出一行包含一个整数,表示答案。
样例输入
1 2 3
1
2 3
4 5 6
样例输出
7
评测用例规模与约定
对于 30% 的评测用例,2 <= n <= 5。
对于所有评测用例,2 <= n <= 60。
考前抱抱佛脚~
哪个大神教教我最后一题最好是c++的代码
3-31:距离省赛9天啦~,应该开始复习之前刷过的题啦,不做新题啦~~~