CSP-X补题报告

我的国庆假期全没了可恶的可达鸭

一、时间方面

考试时间:  2024/10/2 9:00~12:00

时间分配: 第一题和第二题共一个小时,第三题和第四题共65分钟,剩下的时间检查

二、解题思路

第一题:做饭


我一开始想的是把秒,分,时分别表示出来在比较,

但我忽略了隔天情况所以36分……

这是我的代码

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int main(){
	ll a,b,c;//定义输入
	ll a1,b1,c1;
	scanf("%d:%d:%d",&a,&b,&c);
	scanf("%d:%d:%d",&a1,&b1,&c1);
	ll p,q;
	scanf("%d%d",&p,&q);
	ll gong=p+q;
	ll u=gong/60;
	ll v=gong%60;
	ll miao,miaojin,fen,fenjin,shi;
	miao=(v+c)%60;//秒的
	miaojin=(v+c)/60;//秒进的
	fen=(miaojin+u+b)%60;//分的
	fenjin=(miaojin+u+b)/60;//分进的
	shi=(fenjin+a)%24; //时的(这样写没法隔天)所以错了
	if(shi<a1||(shi==a1&&fen<b1)||(shi==a1&&fen==b1&&miao<c1)){
		printf("Yes");
	}
	else{
		printf("No");
	}
	return 0;
}

正确思路是我们可以全部化成秒、1分=60秒,1小时=3600秒,

把他们的和相加再计算。如果sum1<sum2就是可以反之不可以

代码如下

AC代码:

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int main(){
	ll a,b,c;
	ll a1,b1,c1;
	scanf("%lld:%lld:%lld",&a,&b,&c);
	scanf("%lld:%lld:%lld",&a1,&b1,&c1);
	ll p,q;
	scanf("%lld%lld",&p,&q);
	ll gong=p+q;
	ll sum1=c+b*60+a*3600+gong;
	ll sum2=c1+b1*60+a1*3600;
	if(sum1<sum2){
	    cout<<"Yes";
	}
	else{
	    cout<<"No";
	}
	return 0;
}

第二题:评价标准

我运行错误……拿了0分(我真服了)

因为常量N小了,并且我的思路是sort完直接最大的减最小的再减k

没考虑到加k的情况。

这是我的代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const ll N = 1e5+10;
ll n,k,a[N],maxx;
int main(){
	cin>>n>>k;
	for(ll i=1;i<=n;i++){
		cin>>a[i]; 
	}
	sort(a+1,a+1+n);
	ll r=(a[n]-k)-a[1];//一行,想的太简单了
	cout<<r;
	return 0;
}

可以直接暴力枚举 

思路:就是最小的数+k可以还是最小的,可以是最大和最小之间的数,还可以是最大的数;

.就是最小的数-k可以还是最大的,可以是最大和最小之间的数,还可以是最小的数;

可以优化,接下来是优化代码

#include<bits/stdc++.h>
using namespace std;
int n,k,s[10000005],a[10000005],b[10000005],sum1=0,sum2=0;
int main(){
	cin>>n>>k;
	k=abs(k);
	for(int i=1;i<=n;i++){
		cin>>s[i];
		a[i]=s[i];
		b[i]=s[i];
	}
	sort(a+1,a+1+n);
	sort(b+1,b+1+n);
	a[1]+=k;
	b[n]-=k;
	sort(a+1,a+n+1);
	sort(b+1,b+1+n);
	sum1=a[n]-a[1];
	sum2=b[n]-b[1];
	if(sum1<sum2) cout<<sum1;
	else cout<<sum2;
	return 0;
}

第三题: 小可买菜

我想的是双指针

这是我的代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const ll N = 1e5+10;
ll n,k,a[N];
ll sum,maxx;
int main(){
	cin>>n>>k;
	for(ll i=1;i<=n;i++){
		cin>>a[i]; 
	}
	sort(a+1,a+1+n);
	ll q=n,p=1;
	while(k>=1&&q>p&&p<n){
		if(k!=0){
			sum+=a[p];
			q--;
			p++;
			k--;
		}
	}
	for(int i=p;i<=q;i+=2){
		sum+=max(a[i],a[i+1]);
	}
	cout<<sum;
	return 0;
}

用双指针:拿了10分;

但是正解也是双指针,主要的错误是while循环的条件错了,我想的是k>0但是写错了……首指针

和尾指针不能在一起,但是正解是可以相等

下面是正确代码

AC代码:

#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const int N = 1e6+10;
ll n,k;
ll a[N];
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    ll l=1,r=n,sum=0;
    while(k--&&l<=r){
        sum+=a[l];
        l++;
        r--;
    }
    while(l<=r){
        sum+=a[r];
        r-=2;
    }
    cout<<sum;
    return 0;
}

第四题:美味佳肴

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const ll N = 1e5+10;
//char a[30]={!,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,?};
  int  a[30]={9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//标记数组
int main(){
	ll n,sum,cnt;
	cin>>n;  
	while(n--){
		string s;
		cin>>s;
		cnt=0,sum=0;
		int len=s.size();
		for(int i=0;i<len;i++){//把每个字母标记
			if(s[i]=='A') a[1]++;
			if(s[i]=='B') a[2]++;
			if(s[i]=='C') a[3]++;
			if(s[i]=='D') a[4]++;
			if(s[i]=='E') a[5]++;
			if(s[i]=='F') a[6]++;
			if(s[i]=='G') a[7]++;
			if(s[i]=='H') a[8]++;
			if(s[i]=='I') a[9]++;
			if(s[i]=='J') a[10]++;
			if(s[i]=='K') a[11]++;
			if(s[i]=='L') a[12]++;
			if(s[i]=='M') a[13]++;
			if(s[i]=='N') a[14]++;
			if(s[i]=='O') a[15]++;
			if(s[i]=='P') a[16]++;
			if(s[i]=='Q') a[17]++;
			if(s[i]=='R') a[18]++;
			if(s[i]=='S') a[19]++;
			if(s[i]=='T') a[20]++;
			if(s[i]=='U') a[21]++;
			if(s[i]=='V') a[22]++;
			if(s[i]=='W') a[23]++;
			if(s[i]=='X') a[24]++;
			if(s[i]=='Y') a[25]++;
			if(s[i]=='Z') a[26]++;
			if(s[i]=='?') a[27]++;
		}
		for(int i=1;i<=26;i++){//分奇数偶数(已经错了)
			if(a[i]%2==0){
				cnt=cnt+(a[i]/2);
			}
			else{
				cnt=cnt+(a[i]-1)/2;
				sum++;
			}
		}
		if(a[27]!=0&&sum!=0){//用'?'替,但是没看题
			if((a[27]-1)%2==0){
				cnt++;
				cnt+=(a[27]-1)/2;
			}
		}
		printf("%d\n",cnt); 
	}
	return 0;
}

这个题我一点思路都没有只能硬着头皮写,我的思路是错的,我和别人探讨过了

这是我的代码

正确思路是

AC代码:

#include<iostream>
#include<cstring>
using namespace std;
int t;
long long a[95];
string s;
int main(){
    cin>>t;
    while(t--){
        memset(a,0,sizeof a);
        cin>>s;
        int maxx=0;
        long long ans=0;
        int len=s.size();
        int temp;
        for(int i=0;i<len;i++){
            a[s[i]]++;
            if(s[i]!='?'){
                if(a[s[i]]>maxx){
                    maxx=a[s[i]];
                    temp=s[i];
                }
            }
        }
        if(a['?']==0){
            for(int j=65;j<=90;j++){
                ans+=a[j]*(a[j]-1)/2;
            }
        }else{
            a[temp]+=a['?'];
            for(int j=65;j<=90;j++){
                ans+=a[j]*(a[j]-1)/2;
            }
        }
        cout<<ans<<"\n";
    }
    return 0;
}

三、总结

第一题:36

第二题:0

第三题: 10

第四题: 0;

总分: 46

题目有思路,但是不完善

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值