完整版的题解

A题

这道题可以拿字符串写,如果字符串的长度只有2,且组成该字符串的两个字符相同那它就是好数

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'

int main(){
    string a;
    cin>>a;
    if (a.length()==2 && a[0]==a[1])cout<<"Yes";
    else cout<<"No";
    return 0;
}

B题

字符串有三个字符,直接输出第一个和第三个就行

#include<iostream>
using namespace std;
#define endl '\n'

int main(){
    string a;
    cin>>a;
    cout<<a[0]<<a[2];
    return 0;
}

C题

如果x,y,n相等,那他们的最大公约数就是n本身,但题目里说了x和y不相等,那我们令y=2x就好了

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'


int main(){
    int q;
    cin>>q;
    while (q--){
        long long a;
        cin>>a;
        cout<<a<<' '<<a*2<<endl;
    }
    return 0;
}

D题

暴力就能过,但是我也只会暴力

把数的每个数位分开,其中包含x就计数即可

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'

int main(){
    int n,x,ans=0;
    cin>>n>>x;
    for (int i = 1; i <= n; ++i) {
        int temp=i;
        while (temp){
            if (temp%10==x)ans++;
            temp/=10;
        }
    }
    cout<<ans;
    return 0;
}

E计算进位

两个数字相加,会不会出现进位的情况 现在就是小学的加法问题 eg: 1563+654 从尾项开始(即3+4)这个位加完后往前加直到5+6

为什么是5+6? 可以看到这两个数分别是三位和四位 那这个四位的数加一个三位的如果变成了五位,那么这两个数在第三位肯定就进位了,那我们只算到第三位判断是否需要进位

这里可以看出十位(5+6=11)和百位涉及进位 ok了,有这个基础知识就可以开肝

#include<iostream>
#include<string>
#include<algorithm>//reverse的头
using namespace std;
int main()
{
	string a,b;
	cin>>a>>b;
	int x=0;
	int len=a.size()>b.size()?b.size():a.size();//找短的那个的长度
	reverse(a.begin(),a.end());//反转字符串
	reverse(b.begin(),b.end());
	for(int i=0;i<len;i++)
	{
		if((a[i]-'0')+(b[i]-'0')>=10)//判断是否进位
		{
		x=1;//进位的情况,标记x=1
		break;
		}
	}
	if(x)cout<<"Hard";
	else cout<<"Easy";
	return 0;
 } 

F可编程拖拉机比赛

题目意思: 给你一个数,你要计算这个数的0.1,0.2,0.3(对应分别拿金,银,铜的人数),最后拿总数减去拿这几种牌子的人就是拿铁牌的人 分别向上向下取整值为多少,然后计算每个数的向上向下取整后,根据变化,算多少人的奖牌应该换 题目样例115,这里以115为例:

名称 0.1 0.2 0.3 铁
向下取整 11 23 34 115-11-23-34=47
向上取整 12 23 35 45

接下来展示换牌的计算方式 (x[0]为11,y[0]为23,z[0]为34,w[0]为47,w[1]为35,其他类推) 原本按照向下取整发,实际按照向上发

ans1=银->金=x[1]-x[0]

y[1]-y[0]=银牌变化量=银牌增加量-银牌减少量=(铜->银)-(银->金) ans2=(铜->银)=(银->金)+(y[1]-y[0]);

z[1]-z[0]=铜牌变化量(后面和银牌变化量开始都一样) 或者 ans3=(铁->铜)就是铁牌变化量 终于写完了,上代码

#include<bits/stdc++.h>
using namespace std;
int arr[21],brr[21],crr[21];
int main()
{
    int n;
    cin>>n;
    double n1=n;
    //这边存int n,n/10就是直接向下取整
    //floor也能直接向下取整(取整得要对浮点型数据才有用,整形没必要)
    int x[2]={0,0},y[2]={0,0},z[2]={0,0},w[2]={0,0};
    int ans[4];
    for(int i=0;i<4;i++)ans[i]=0;
    x[0]=n/10;
    y[0]=(n*0.2);
    z[0]=n*0.3;
    w[0]=n-x[0]-y[0]-z[0];
    x[1]=ceil(n1/10);
    y[1]=ceil(n1*0.2);
    z[1]=ceil(n1*0.3);
    w[1]=n-x[1]-y[1]-z[1];
    ans[0]=fabs(x[1]-x[0]);
    ans[1]=fabs(y[1]-y[0]);
    ans[2]=fabs(z[1]-z[0]);
    ans[3]=fabs(w[1]-w[0]);
 
//    cout<<x[0]<<" "<<x[1]<<endl;
//    cout<<y[0]<<" "<<y[1]<<endl;
//    cout<<z[0]<<" "<<z[1]<<endl;
//    cout<<w[0]<<" "<<w[1]<<endl;
//   
//    for(int i=0;i<4;i++)cout<<"ans["<<i<<"]="<<ans[i]<<" ";
//    cout<<endl;
     
    cout<<ans[0]<<" "<<ans[1]+ans[0]<<" "<<ans[3]<<" ";
    return 0;
 }

G题

法1(队列法)

简单来说就是一个边出边存的小问题 用经典的队列解决约瑟夫环 https://blog.csdn.net/m0_51506743/article/details/124004350 有了这个前置知识就是在该问题基础上先走k次 比较简单就直接上代码了

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,k,m;
	cin>>n>>k>>m;
	queue<int>q;
	for(int i=0;i<n;i++)
	{
		q.push(i);
	}
	int f=0;
	while(k--)
	{
		f=q.front();
		q.pop();
		q.push(f);
	}
	int j=1;
	while(q.size()!=1)
	{
		if(j==m)
		{
		f=q.front();
		q.pop();
		j=1;
		}
		else{
		f=q.front();
		q.pop();
		q.push(f);
		j++; 
		} 
	}
	cout<<q.front();
	return 0;
 } 

法2(公式法)

先常规的上连接:https://blog.csdn.net/u011500062/article/details/72855826 ok了啊兄弟们 直接上代码

#include <iostream>
using namespace std;
void solve(int n,int k,int m) {
    int p=0; 
    for(int i=2;i<=n;i++) p=(p+m)%i;
    cout<<(p+k)%n<<endl;; 
}
int main()
{
    int n,k,m;
    cin >> n >> k >> m;
    solve(n,k,m);
    return 0;
}

H题

前置知识

  • gcd(m,n)=n?gcd(n,m%n):m;
  • lcm=m∗n/gcd(m,n)

首先,这题真的简单

gcd与lcm,这边提供两种思路及3种AC代码。

首先,我们看题目不难发现,一共给了2种数据

分别是日期的gcd值和lcm值。

解法1

首先我们不难想到,全部搜一遍,查看是否存在多个日期的gcd和lcm与目标相同。

于是下面的代码

#include<bits/stdc++.h>
#include<cmath>
using namespace std;

const int N =1e6+10;
typedef pair<int,int> PII;
typedef long long ll;

bool pd(int a,int b){
    if(a==1||a==3||a==5||a==7||a==8||a==10||a==12){
        if(b<=0||b>31)return false;
    }
    else if(a==2){
        if(b<=0||b>29)return false;
    }
    else{
        if(b<=0||b>30)return false;
    }
    return true;
}

void solve(){
    int n,m;
    cin>>n>>m;
    vector<PII>vt;
    for(int i=1;i<=12;i++){
        for(int j=1;j<=31;j++){
            if(lcm(i,j)==n&&gcd(i,j)==m){
                vt.push_back({i,j});
            }
        }
    }
    for(int i = vt.size()-1;i>=0;i--){
        int a =  vt[i].first,b=vt[i].second;
        if(pd(a,b)==false){
            vt.erase(vt.begin() + i);
        }
    }

    if(vt.size()==1){
        cout<<"YES"<<endl;
    }
    else{
        cout<<"NO"<<endl;
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int tt = 1;
    cin>>tt;
    while(tt--){
        solve();
    }
    return 0;
}

那么这种方法太慢了,平均每组样例的解决时间复杂度是O(n∗m)O(nm),也就是大约要12*30次判断才能做出一组数据。

解法2,稍稍优化一下思路

上面的判断实在是太复杂了,每一个都去判断。

但是,有没有一种可能,

其实月份和日期随便选一个去判断,另一个其实同时也判断出来了。

由于已知 gcd∗lcm=date∗month,同时,令t为月份日期的积,我们用i去遍历月份,t/i其实就是日期。

接下来只需要判断 i 和 t/i 的gcd和lcm是否符合题目给出的,如果符合就用cnt计数。

遍历完12个月之后,判断 cnt=1 ,符合这个条件说明是唯一的,否则就是存在其他日期符合条件。

上AC 代码↓

#include <bits/stdc++.h>
#define int long long
using namespace std;

void zxy()
{
    int n,m;cin>>n>>m;
    int num = n * m;
    int month[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
    int cnt = 0;
    for(int i=1;i<=12;i++)
    {
        if(num%i==0&&num/i<=month[i-1]&&gcd(i,num/i)==m&&lcm(i,num/i)==n) cnt ++;
    }
    if(cnt == 1) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}

signed main()
{
    int t; cin>>t;
    while(t --) zxy();
    return 0;
}

解法3(暴力打表)

这个是出题时候写的解法,应该是本题目在数据量较大的情况下比较好的解法。

我们先建立一个二维数组,横纵坐标分别是gcd和lcm,一个1000,一个40足够了。

接下来预处理数据,遍历每个日期,计算gcd和lcm,并在对应的下标++,用于统计。

接下来只需要读入gcd和lcm,然后去数组里面查询是否唯一即可。

参考代码↓

#include "bits/stdc++.h"
using namespace std;
int main()
{
	int mp[373][32];
	memset(mp,0,sizeof mp);
	for(int i=1;i<13;i++)
	{
		for(int j=1;j<32;j++)
		{
			mp[lcm(i,j)][gcd(i,j)]++;
		}
	}
	int q;cin>>q;
	while(q--)
	{
		int l,g;cin>>l>>g;
		if(mp[l][g]==1)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

记得补题

I题

答案是3181,代码直接这么写就行了↓

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'

int main(){
    cout<<3181;
    return 0;
}

我的结果是模拟出来的,除了模拟我也不会别的

先设定一个长度为9的数组,填充上2021,模拟每种卡片的数量,用n表示当前试图拼的数字

如果某种卡片数量已经到0了,那就拼不出n,能拼出来最大的就是n-1

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'

int main(){
    int arr[9];
    fill(arr,arr+9,2021);
    int n=0;
    while (1){
        n++;
        cout<<n<<endl;
        int temp=n;
        while (temp){
            if (arr[temp%10]<=0){cout<<n-1;return 0;}
            else arr[temp%10]--;
            temp/=10;
        }
    }
}
全部评论

相关推荐

07-11 11:10
门头沟学院 Java
请问各位大三兄弟们跟hr说多久实习时间到时候可以提前跑路吗?
程序员小白条:问就是六个月以上,可以一年,实习都这样,你入职后想跑就跑
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务