Mamba's Helicopter 坠机大赛 第4场 题解
传送门:https://www.luogu.com.cn/contest/232586
A题 https://www.luogu.com.cn/problem/P1420
循环结构。
C++题解:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int n, a[10000], count=1, ans=1;//count用于记录当前连号长度,ans记录最长连号
int main() {
scanf("%d\n", &n);
for(int i=1; i<=n; i++){
cin>>a[i];//循环读入
}
for(int i=2; i<=n; i++){
if(a[i]==a[i-1]+1) count++;//判定是否连号,是则连号长度+1
if(count>ans) ans=count;//更新最长连号
if(a[i]!=a[i-1]+1) count=1;//否则重置当前连号
}
cout<<ans;//输出答案
return 0;
}
Java题解:
点击查看代码
import java.util.Scanner;
public class Main {//洛谷平台Java语言评测时主类名必须是Main
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);//创建输入
int n=scanner.nextInt();//输入n
int num, tmp=0, sum=1, ans=0;//num记录当前读入的数,tmp记录上一个读入的数,sum为当前连号长度,ans为最长连号
for(int i=1; i<=n; i++){
num=scanner.nextInt();//循环结构内读入n
if(i>1){//从第二位开始判断,否则会RE
if(num==tmp+1) sum++;//连号则+1
else sum=1;//否则重置连号
if(sum>ans) ans=sum;//更新连号长度
}
tmp=num;//更新“上一个”读入的数
}
System.out.println(ans);//输出答案
}
}
B题 https://www.luogu.com.cn/problem/P3741
字符串。由于至多改变一个字符,所以思路为先判断字符串中已有的"VK"数量,然后判断改变一个字符是否能够使"VK"数量+1。
C++题解:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, count=0, row=0;//count为已有“VK”,row记录是否能通过改变一个字符使"VK"数量+1
string str;
cin>>n;
cin>>str;
if(n==1) cout<<0;//如果字符串长度为1,显然“VK”数量为0
else{
for(int i=0; i<n-1; i++){//以下部分为情况枚举,情况多且方法较蠢。可查看下面一篇Java题解,逻辑更简洁清晰
if(str[i]=='V'){
if(str[i+1]=='K'){
count++;//V和K相邻,“VK”数量++
}
if(str[i+1]=='V' && str[i+2]!='K') row=1;//多个V相邻,可以改变中间的一个V为K
}
if(str[i]=='K'){
if(i-1>=0){
if(str[i-1]!='V' && str[i+1]=='K') row=1;//多个K相邻且首K前不是V
}
if(i-1<0){
if(str[i+1]=='K') row=1;//字符串首为K
}
}
}
if(row==1) count++;//若能通过改变一个字符使"VK"数量+1,数量++
cout<<count;
}
return 0;
}
Java题解:
点击查看代码
import java.util.*;
public class Main{
public static void main(String[] args) {
int n, ans=0;
boolean[] vis = new boolean[1000];
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
String s = sc.next();
char[] ch = s.toCharArray();//转化为字符数组
for(int i=0; i<n-1; i++){
if(ch[i]=='V' && ch[i+1]=='K'){//判断原有“VK”数量
ans++;
vis[i]=vis[i+1]=true;
}
}
for(int i=0; i<n-1; i++){
if(!vis[i] && !vis[i+1] && (ch[i]=='V'||ch[i+1]=='K')){//判断是否可以改变一个字符使“VK”数量+1
ans++;
break;
}
}
System.out.println(ans);
}
}
C题 https://www.luogu.com.cn/problem/P11076
用countF表示小F已赢得的场数,如果他要获胜,那么还需要赢x-countF场。要使他的连胜场数最少,那么就要尽可能均匀地在这里面插入小S获胜的场次,至多插入y-countS场。
C++题解:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
char str[200010];
long long T, i, k;
long long n, x, y, countF, countS, ans;
double tmp;
int main() {
for(i=0; i<2000; i++){
str[i]='\0';//清空字符数组
}
scanf("%lld", &T);
for(i=1; i<=T; i++){
countF=0;
countS=0;
scanf("%lld %lld %lld", &n, &x, &y);
scanf("%s", str);//读入当前单挑结果
for(k=1; k<=n; k++){
if(str[k-1]=='F'){
countF++;
}
if(str[k-1]=='S'){
countS++;
}
}
if(y-countS==1){
ans=x-countF;//如果小S只差一局就赢了,那么小F要全胜
}
else{
tmp=(x-countF)/(y-0.0-countS);//均分小F的胜场为y-countS份
ans=ceil(tmp);//向上取整
}
printf("%lld\n", ans);
}
return 0;
}
D题 https://www.luogu.com.cn/problem/T578004
C++题解(常规做法):
点击查看代码
#include<bits/stdc++.h>
using namespace std;
//By dzx,枚举
int main(){
int n,m,x,y,c=0;
cin>>n>>m>>x>>y;
for(int i=x,j=y;i>=0&&j>=0;i--,j--){
c++;
}
for(int i=x,j=y;i<=n&&j>=0;i++,j--){
c++;
}
for(int i=x,j=y;i>=0&&j<=m;i--,j++){
c++;
}
for(int i=x,j=y;i<=n&&j<=m;i++,j++){
c++;
}
cout<<c-4;
return 0 ;
}
另一C++题解:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
//By grh,大道至简
int n,m,x,y,ans;
int main(){
cin >> n >> m >> x >> y;
ans = min(x,y) + min(y,n-x) + min(n-x,m-y) + min(m-y,x);
cout << ans;
return 0;
}
E题
经典高精题。
C++题解:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int n, len=1;
int ans[1000];//用数组存储答案
int main(){
cin>>n;
ans[1]=1;//初值赋1
if(n==0){
cout<<1;//特判,0!=1
return 0;
}
else{
for(int i=1; i<=n; i++){
for(int j=1; j<=len; j++){//模拟每一位的乘法
ans[j]*=i;
}
for(int j=1; j<=len; j++){//处理进位
ans[j+1]+=ans[j]/10;
ans[j]%=10;
while(ans[len+1]) len++;
}
}
for(int i=len; i>=1; i--){
cout<<ans[i];//输出
}
return 0;
}
}
Java题解:
点击查看代码
import java.math.BigInteger;
import java.util.Scanner;
//Java自带大数高精,但是第4和第5测试点会超出3MB内存限制
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
if(n==0) System.out.println(1);
else{
BigInteger factorial = calculateFactorial(n);
System.out.println(factorial);
}
}
public static BigInteger calculateFactorial(int number) {
BigInteger result = BigInteger.ONE;
for (int i = 1; i <= number; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
}
F题
结构体+排序
C++题解:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int n;
struct man{
int eng, math;//创建结构体,eng和math分别记录英语和数学成绩
} m[30];
int cmp(man x, man y){//排序策略
if(x.eng==y.eng) return x.math>y.math;//如果英语相同,数学分高者在前
return x.eng>y.eng;//否则英语分高者在前
}
int main(){
cin>>n;
for(int i=1; i<=n; i++){
cin>>m[i].eng>>m[i].math;
}
sort(m+1, m+1+n, cmp);//排序
for(int i=1; i<=n; i++){
cout<<m[i].math<<endl;
}
return 0;
}