第一题大意 :小明喜欢吃糖果,但是糖果吃多了会蛀牙
给你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;
}