本文主要是介绍ACM实训冲刺第二十一天,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
寒冰王座(数据处理与逻辑判断)
这段C语言代码实现了一个根据特定条件计算整数输入值变换的程序,它并不直接对应于经典的算法题类型,但可以视为一个“数据处理与逻辑判断”练习题。代码的主要逻辑如下:
读取测试数据数量 (
T
):首先读取一个整数T
,表示有多少组测试数据。如果T
不在1到100的范围内,则结束输入。循环处理每组测试数据:对于每组数据,执行以下操作:
- 初始化变量
sum
为0。- 读取一个正整数
n
,如果n
不在1到10000的范围内,结束当前循环。- 根据
n
的值应用不同的计算规则:
- 如果
n >= 300
,则sum = n % 50
(取模运算)。- 如果
150 <= n < 200
,则sum = n - 150
。- 如果
200 <= n < 300
,则sum = n - 200
。- 如果
n < 150
,则sum = n
。- 输出计算结果
sum
。错误的边界检查位置:代码中有一处逻辑错误,在外层循环结束后再次检查了
n
的范围,但这实际上在循环结束后已经失去了意义,因为此时n
的值未被重新定义,且这一检查并不能终止程序或改变程序流程,应视为冗余或错误代码。
#include <stdio.h>
int main(){int T,i,n,sum;while(scanf("%d",&T)!=EOF){ //T代表的是测试数据的数量 if(T<1||T>100) break;for(i=0;i<T;i++){int sum=0;//初始化置0scanf("%d",&n) ;//正整数Nif(n<1||n>10000) break;if(n>=300) sum=n%50;else if(n<200&&n>=150) sum=n-150;else if(n<300&&n>=200) sum=n-200;else if(n<150) sum=n;printf("%d\n",sum);}}return 0;
}
Charm Bracelet(0-1背包问题)
这段代码实现的是一个经典的动态规划问题——0-1背包问题。0-1背包问题是一种组合优化问题,问题描述为:给定一组物品,每种物品都有自己的重量W和价值V,以及一个背包所能承载的最大重量M,要求在不超过背包最大重量的前提下,挑选物品装入背包,使得背包中物品的总价值最大。
代码解析如下:
- 输入: 首先读取两个整数
n
和m
,分别代表物品的总数和背包的最大容量。- 初始化: 定义一个数组
dp
,长度为12881
(这里的长度选择是基于题目的实际情况,确保能覆盖到背包最大容量的情况),并初始化所有dp[i]
为0。dp[i]
表示当背包容量为i
时,能够装入物品的最大价值。- 动态规划转移: 遍历每一件物品(编号为1到n),对于每件物品,读取其重量
w
和价值d
,然后从当前背包容量m
反向遍历到这件物品的重量w
,更新dp[j]
的值。如果将当前物品装入背包(即考虑之前容量为j-w
的情况,并加上当前物品的价值d
)能得到更大的价值,就更新dp[j]
的值为这个更大的价值。这是动态规划中典型的“状态转移”过程。- 输出结果: 最终,
dp[m]
存储的就是在背包容量为m
时能装入物品的最大总价值,将其输出即为答案。
#include<stdio.h>
int main() {int n,m;scanf("%d %d",&n,&m);int dp[12881];for(int i=0;i<m;i++){dp[i]=0;}for(int i=0;i<n;i++){int d,w;scanf("%d %d",&w,&d);for(int j=m;j>=w;j--){//注意条件 if(dp[j-w]+d>dp[j]){dp[j]=dp[j-w]+d;}}}printf("%d\n",dp[m]);return 0;
}
Vanya and Lanterns(最大覆盖半径)
实现的算法主要是基于排序和扫描的方式来解决一个具体问题,即找出能够使得所有路段上的点都被路灯覆盖所需的最小最大半径。具体步骤如下:
输入读取:首先读取路灯数量(n)和路的总长度(l),然后读取每个路灯所在的位置。
排序:使用
std::sort
函数对路灯位置数组进行排序,这样可以确保位置按升序排列,便于后续处理。最大间距计算:通过遍历排序后的路灯位置数组,计算相邻路灯之间的距离并取其中的最大值的一半作为可能的最大覆盖半径的一个候选值。这是因为任何位置上的点到相邻两个路灯的最远距离不会超过这两个路灯间距的一半。
处理边界情况:检查第一个和最后一个路灯位置与路的两端点的关系,以确定是否存在路的两端没有直接被路灯覆盖的情况。如果路的开始位置或结束位置没有路灯,则需要将这些未覆盖的路段长度与之前计算的最大间距的一半比较,取其中的最大值作为实际的最大覆盖半径。
输出结果:最后输出计算得到的最大覆盖半径,保留10位小数。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
double ans=0;
int n;
int l;
double loc[1001];
int main(){scanf("%d %d",&n,&l);for(int i=0;i<n;i++)scanf("%lf",&loc[i]);sort(loc,loc+n) ;for(int i=0;i<n;i++)ans=max(ans,(loc[i]-loc[i-1])/2.0) ;if(loc[0]!=0)ans=max(ans,loc[0]) ;if(loc[n-1]!=l)ans=max(ans,l-loc[n-1]) ;printf("%.010lf\n",ans);return 0;
}
Anton and Danik(数值运算与字符串处理)
这段代码运用的是计数/统计算法思路来解决问题。具体步骤如下:
输入处理:首先,程序读取一个整数
n
,表示字符串s
的长度。随后,读取一个长度为n
的字符串s
,该字符串只包含字符'A'和'D'。统计字符:通过遍历字符串
s
,使用两个计数器cntA
和cntD
分别记录字符'A'和'D'出现的次数。这是通过一个简单的循环实现的,每次遇到字符'A'就增加cntA
的值,遇到'D'就增加cntD
的值。结果判断:遍历结束后,根据
cntA
和cntD
的值来判断并输出结果:
- 如果
cntA
大于cntD
,则输出"Anton",表示字符'A'(代表Anton)出现次数更多。- 如果
cntD
大于cntA
,则输出"Danik",表示字符'D'(代表Danik)出现次数更多。- 代码中存在一处逻辑错误,应使用
==
而非=
, 正确的判断条件应该是else if(cntA == cntD)
,此时输出"Friendship",表示两者出现次数相等,象征友谊。
#include<stdio.h>
#include<string.h>
#define MAX_N 100000
int main() {int n;scanf("%d",&n);char s[MAX_N];scanf("%s",s);int cntA=0,cntD=0;for(int i=0;i<n;i++){if(s[i]=='A')cntA++;else if(s[i]=='D')cntD++;}if(cntA>cntD)printf("Anton\n"); else if(cntD>cntA)printf("Danik\n"); else if(cntA=cntD)printf("Friendship\n");return 0;
}
题型统计
练习题名称 | 数学计算与序列求和 | 数值运算与字符串处理 | 频率统计题 | 数据处理与逻辑判断 | 0-1背包问题 | 最大覆盖半径 |
SUM Problem | √ | |||||
A+B problem | √ | |||||
Anton and letters | √ | |||||
Sum of digits | √ | |||||
寒冰王座 | √ | |||||
Charm Bracelet | √ | |||||
Vanya and Lanterns | √ | |||||
Anton and Danik | √ |
这篇关于ACM实训冲刺第二十一天的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!