第七届传智杯第一场初赛b组补题➕题解

第一题大意 :小明喜欢吃糖果,但是糖果吃多了会蛀牙
给你n个糖果,每个糖果有一定的甜度值,甜度值达到k就会蛀牙,小明想在蛀牙前吃到最多的糖果
输出小明能吃到的最多的糖果的个数

思路:就是排序后求累和,简单贪心
 

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int mod=1e9+7;
ll n,k;
ll dp[300000]; 
ll a[300000];
ll sum;
int num=0;

int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)cin>>a[i];
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		sum=sum+a[i];
		if(sum<=k)
		num++;
		else
		{
			break;
		}
	}
	cout<<num;

	return 0;
}

第二题大意:q次询问,每次给定一个数字,你可以将这个数字的数位任意排序,输出一个排序后的偶数(如果原数是偶数的话可以不排序直接输出),如果有多个答案,任意输出即可

思路:先特判原数是否为偶数(末尾数位是否对2求余为0),不是就从前往后枚举数位,判断当前数位是否对2求余为0,是就与末尾交换位置后直接输出即可。(直接按字符串处理更方便)

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int mod=1e9+7;
int q;

int main(){
	cin>>q;
	while(q){
		q--;
		string s;
		cin>>s;
		int n=s.length();
		int x=s[n-1]-'0';
		if(x%2==0){
			cout<<s<<"\n";
		}else
		{ int i=0;
			for( i=0;i<n;i++){
				int y=s[i]-'0';
				if(y%2==0){
					char ss=s[i];
					s[i]=s[n-1];
					s[n-1]=ss;
					cout<<s<<"\n";
					i=10000000;
				}
			}
			if(i==n)cout<<"-1"<<"\n";
			
		}
	}
	return 0;
}

第三题大意:给定不定数量的字符串,判断其中开心表情的颜文字多还是伤心表情的颜文字多,开心多输出happy,伤心多输出sad,都为0输出none,相等输出Just so so

思路:就一枚举判断,一个小知识点是如何在没有给定数据规模的情况下判断截止输入,方法也很多,我采取的是用getchar()判断换行符

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int mod=1e9+7;
char s[1000];
int happy,sad; 

int main(){
	int l=0;
	while(1){
		string ss;
		cin>>ss;
		
		int n=ss.length();
		for(int i=l;i<l+n;i++){
			s[i]=ss[i-l];
		}
		l=l+n;
		
		int x=getchar();
		if(x =='\n')
		break;
	}
	for(int i=0;i<l;i++){
		if(s[i]==':' && s[i+1]=='-' && s[i+2]==')')
		{
			happy++;
			i=i+2;
		}
		else
		if(s[i]==':' && s[i+1]=='-' && s[i+2]=='('){
			sad++;
			i=i+2;
		}
	}
	if(happy==sad){
		if(happy==0)
		cout<<"None";
		else
		cout<<"Just so so";
	}
	else
	if(happy>sad){
		cout<<"Happy";
	}
	else
	cout<<"Sad";

	return 0;
}

第四题大意:给定n个点的坐标,将这些点任意连线组成线段,求出这些线段与坐标轴最对有几个交点,特别的通过原点视为与坐标轴有2个交点

思路:简单数学,相对象限的点相连与坐标轴有2个交点,相邻象限的点相连与坐标轴有1个交点。先判断相对,再判断相邻

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int mod=1e9+7;

ll n;
ll x[200000],y[200000]; 
ll x1,x2,x3,x4;
ll sum;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>x[i]>>y[i];
		if(x[i]>0 && y[i]>0)
		x1++;
		else
		if(x[i]<0 && y[i]>0)
		x2++;
		else
		if(x[i]<0 && y[i]<0)
		x3++;
		else
		if(x[i]>0 && y[i]<0)
		x4++;
		
	}
	ll mm=min(x1,x3);
	x1=x1-mm;
	x3=x3-mm;
	ll mn=min(x2,x4);
	x2=x2-mn;
	x4=x4-mn;
	sum=mm*2+mn*2+sum;
	ll mmm=max(max(x1,x2),max(x3,x4));
	sum=sum+x1+x2+x3+x4-mmm;
//下述是枚举判断哪两象限不为0,再进行相加,也可以直接用上述代码进行判断 
//	if(x1==0 && x2==0){
//		ll mmm=min(x3,x4);
//		sum=sum+mmm;
//	}
//	else
//	if(x1==0 && x4==0){
//		ll mmm=min(x3,x2);
//		sum=sum+mmm;
//	}
//	else
//	if(x3==0 && x2==0){
//		ll mmm=min(x1,x4);
//		sum=sum+mmm;
//	}
//	else
//	if(x3==0 && x4==0){
//		ll mmm=min(x1,x2);
//		sum=sum+mmm;
//	}

	cout<<sum;
	

	return 0;
}

第五题大意:五子棋的简略版四子棋,给定一个棋盘,判断是否有棋子连成4个及以上

思路:模拟/穷举所有的可能(行,列,主副对角线)

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int mod=1e9+7;
int n,m;
int a[200][200];//1为红 2为紫 0为没有落 
//priority_queue<PII, vector<PII>, greater<PII>> heap;
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		string s;
		cin>>s;
		int l=s.length();
		for(int j=1;j<=l;j++){
			if(s[j-1]=='r')
			a[i][j]=1;
			else
			if(s[j-1]=='p')
			a[i][j]=2;
		}
	}
	//判断行 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]==1 &&a[i][j+1]==1 && a[i][j+2]==1 && a[i][j+3]==1 ){
				cout<<"kou";return 0;
			}
			if(a[i][j]==2 && a[i][j+1]==2 && a[i][j+2]==2 && a[i][j+3]==2 ){
				cout<<"yukari";return 0;
			}
		}
	}
	//判断列 
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			if(a[j][i]==1 &&a[j+1][i]==1 && a[j+2][i]==1 && a[j+3][i]==1 ){
				cout<<"kou";return 0;
			}
			if(a[j][i]==2 &&a[j+1][i]==2 && a[j+2][i]==2 && a[j+3][i]==2 ){
				cout<<"yukari";return 0;
			}
		}
	}
	//判断主对角线 及往上 
	for(int i=1,j=1;j<=m;j++){
		int x=i,y=j;
		while(x<=n){
			if(a[x][y]==1 && a[x+1][y+1]==1 && a[x+2][y+2]==1 && a[x+3][y+3]==1){
				cout<<"kou";return 0;
			}
			if(a[x][y]==2 && a[x+1][y+1]==2 && a[x+2][y+2]==2 && a[x+3][y+3]==2){
				cout<<"yukari";return 0;
			}
			x++;y++;
		}
	} 
	//判断主对角线及往下 
	for(int i=1,j=1;i<=n;i++){
		int x=i,y=j;
		while(y<=m){
			if(a[x][y]==1 && a[x+1][y+1]==1 && a[x+2][y+2]==1 && a[x+3][y+3]==1){
				cout<<"kou";return 0;
			}
			if(a[x][y]==2 && a[x+1][y+1]==2 && a[x+2][y+2]==2 && a[x+3][y+3]==2){
				cout<<"yukari";return 0;
			}
			x++;y++;
		}
	} 
	//判断副对角线及往上 
	for(int i=1,j=m;j>=3;j--){
		int x=i,y=j;
		while(y>=3){
			if(a[x][y]==1 && a[x+1][y-1]==1 && a[x+2][y-2]==1 && a[x+3][y-3]==1){
				cout<<"kou";return 0;
			}
			if(a[x][y]==2 && a[x+1][y-1]==2 && a[x+2][y-2]==2 && a[x+3][y-3]==2){
				cout<<"yukari";return 0;
			}
			x++;y--;
		}
	}

	//判断副对角线及往下
	for(int i=1,j=m;i<=n;i++){
		int x=i,y=j;
		while(y>=3){
			if(a[x][y]==1 && a[x+1][y-1]==1 && a[x+2][y-2]==1 && a[x+3][y-3]==1){
				cout<<"kou";return 0;
			}
			if(a[x][y]==2 && a[x+1][y-1]==2 && a[x+2][y-2]==2 && a[x+3][y-3]==2){
				cout<<"yukari";return 0;
			}
			x++;y--;
		}
	}



	
	
	cout<<"to be continued";
	return 0;
}

第六题大意:给定一个数组,进行k次操作,每次可以将数组中的任意一个数减小x,求最小的最大值

思路:考试时不会写考完问的ai,仅供参考

#include <iostream>
#include <vector>

using namespace std;
using ll = long long;

const int mod = 1e9 + 7;

int main() {
    ll n, k, x;
    cin >> n >> k >> x;
    vector<ll> arr;

    for (int i = 0; i < n; ++i) {
        ll a;
        cin >> a;
        arr.push_back(a);
    }

    sort(arr.begin(), arr.end());  // 先排序,时间复杂度 O(n log n)

    while (k--) {
        arr[0] -= x;  // 直接操作最大值,时间复杂度 O(1)
        if (arr[0] < arr[1]) {  // 如果最大值小于次大值,调整位置
            ll temp = arr[0];
            int j = 0;
            while (j < n - 1 && arr[j + 1] > temp) {
                arr[j] = arr[j + 1];
                j++;
            }
            arr[j] = temp;
        }
    }

    cout << arr[0] << endl;

    return 0;
}

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值