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;
}
posted @ 2025-02-27 16:55  EndeavorCHN  阅读(35)  评论(0)    收藏  举报