目录
1.🌟距离和
📕题目描述:
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
两个字母之间的距离定义为它们在字母表中位置的距离。例如 A 和 C 的距离为 2,L 和 Q 的距离为 5。
对于一个字符串,我们称字符串中两两字符之间的距离之和为字符串的内部距离。
例如:ZOO 的内部距离为 22,其中 Z 和 O 的距离为 11。
请问,LANQIAO 的内部距离是多少?
☀️思路:
简单模拟题
✏️代码 :
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
string s="LANQIAO";
//abcdefghijklmnopqrstuwxyz
int sum;
int main(){
for(int i=0;i<s.size()-1;i++){
for(int j=i+1;j<s.size();j++){
if(s[i]>s[j]){
sum+=s[i]-s[j];
}else{
sum+=s[j]-s[i];
}
}
}
cout<<sum;
return 0;
}//162
2.🌟扩散
📕题目描述:
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝在一张无限大的特殊画布上作画。
这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。
小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)
只有这几个格子上有黑色,其它位置都是白色的。
每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。
请问,经过 2020 分钟后,画布上有多少个格子是黑色的
☀️思路:
多源bfs。将几个点全部入队,使用d数组来记录时间(步长),每走过一个点,vis数组标记为true,最后记录所有vis数组为true的数量。注意:坐标点有负数情况,所以先提前处理好,将所有点横纵坐标+3000
✏️代码 :
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<queue>
using namespace std;
const int N=10000;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
bool vis[N][N];
int d[N][N];//步数即时间
struct Node{
int x;
int y;
};
void bfs(){
queue<Node>q;
memset(vis,false,sizeof(vis));
memset(d,-1,sizeof(d));
q.push({3000, 3000}); d[3000][3000] = 0;
q.push({5020, 3011}); d[5020][3011] = 0;
q.push({3011, 3014}); d[3011][3014] = 0;
q.push({5000, 5000}); d[5000][5000] = 0;
vis[3000][3000] = 1;vis[5020][3011]= 1;
vis[3011][3014] = 1;vis[5000][5000] = 1;
while(q.size()){
Node t=q.front();
q.pop();
if(d[t.x][t.y]==2020) return;//时间到达2020 结束
for(int i=0;i<4;i++){
int fx=t.x+dx[i],fy=t.y+dy[i];
if(fx<0||fx>10000||fy<0||fy>10000) continue;
if(vis[fx][fy]) continue;
if(d[fx][fy]!=-1) continue;
q.push({fx,fy});
vis[fx][fy]=1;
d[fx][fy]=d[t.x][t.y]+1;//时间加一
}
}
}
int main(){
bfs();
int ans=0;//别忘了初值设0
for(int i=0;i<10000;i++){
for(int j=0;j<10000;j++){
if(vis[i][j]) ans++;
}
}
cout<<ans;
return 0;
}//20312088
3.🌟错误票据
📕题目描述:
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。
输入格式
要求程序首先输入一个整数N(N<100)表示后面数据行数。
接着读入N行数据。
每行数据长度不等,是用空格分开的若干个(不大于100个)正整数(不大于100000),请注意行内和行末可能有多余的空格,你的程序需要能处理这些空格。
每个整数代表一个ID号。
输出格式
要求程序输出1行,含两个整数m n,用空格分隔。
其中,m表示断号ID,n表示重号ID
输入:
2
5 6 8 11 9
10 12 9
输出
7 9
☀️思路:
一开始在dev里跑不出结果,在蓝桥云课评测里能通过,后来问了大佬,要用ctrl+d或者在末尾输eof来结束输入,才能成功输出答案。
题目本身没有什么难度,就把输入的所有数放入a数组,再对a进行递增排序,遍历a中所有数,
a[i]==a[i+1]为重号,a[i]+1!=a[i+1]为断号
✏️代码 :
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+10 ;
int n;
int a[N];
int x,y;
int i,j;
string s;
int main(){
cin>>n;
while(cin>>a[i]){
i++;
}
sort(a,a+i);
for( j=0;j<i-1;j++){
if(x!=0&&y!=0) break;
if(a[j]==a[j+1]){
x=a[j];//重号
}else if(a[j]+1!=a[j+1]){
y=a[j]+1;//断号
}
}
cout<<y<<" "<<x;
return 0;
}//编译器里要用ctrl+d结束程序运行才能输出
//或者加eof
4、🌟倍数问题
📕题目描述:
众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。
输入描述
第一行包括 2 个正整数 n, Kn, K。
第二行 n 个正整数,代表给定的 n 个数。
其中,,,给定的n个数不超过
输出描述
输出一行一个整数代表所求的和。
输入
4 3
1 2 3 4
输出
9
☀️思路
三维01背包加取模优化(不会优化)
闫氏dp分析法
状态表示:f(i,j,k)
- 集合:从所有前i个数中选且已经选了j个数且总和模k的余数是k的选择的集合
- 属性:Max
状态计算:选与不选第i个物品
- 选择第i个物品:f(i-1,j-1,k-a[i]%k)
- 不选择第i个物品:f(i-1,j,k)
为了防止负数取模出现错误的情况,所以对x取模记为 x mod k + k
(普通的dp做法WA了,不会优化)😢
✏️暴力代码 : (能骗60%的分数)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+10 ;
typedef long long ll;
ll a[N];
int n,m;
ll ans=0;
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%lld",&a[i]);
}
for(int i=0;i<n;i++){
for(int j=0;j<n&&i!=j;j++){
for(int k=0;k<n&&j!=k&&i!=k;k++){
ll sum=a[i]+a[j]+a[k];
if(sum>ans&&sum%m==0){
ans=sum;
}
}
}
}
printf("%lld",ans);
return 0;
}
✏️未通过dp代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10, M=1010;
int n, m;
int a[N];
int f[N][5][M];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d", &a[i]);
memset(f, -0x3f, sizeof f);
for(int i=0;i<=n;i++) f[i][0][0]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=3;j++)
for(int k=0;k<m;k++)
f[i][j][k]=max(f[i-1][j][k], f[i-1][j-1][((k-a[i])%m+m)%m]+a[i]);
int ans=-1;
for(int i=1;i<=n;i++) ans=max(ans, f[i][3][0]);
cout<<ans<<endl;
}

这篇博客探讨了四个编程题目:计算字符串内部距离的简单模拟,扩散问题的多源BFS解决,错误票据的断号与重号查找,以及寻找最大和为倍数的三数之和问题。文章详细解析了思路并提供了代码实现,适合提升编程思维和算法能力。
1100

被折叠的 条评论
为什么被折叠?



