H题 题目解析

H题

前置知识

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

首先,这题真的简单

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;
}

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

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

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

但是,有没有一种可能,

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

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

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

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

上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;
}

记得补题

全部评论

相关推荐

想干测开的tomca...:让我来压力你!!!: 这份简历看着“技术词堆得满”,实则是“虚胖没干货”,槽点一抓一大把: 1. **项目描述是“技术名词报菜名”,没半分自己的实际价值** 不管是IntelliDoc还是人人探店,全是堆Redis、Elasticsearch、RAG这些时髦词,但你到底干了啥?“基于Redis Bitmap管理分片”是你写了核心逻辑还是只调用了API?“QPS提升至1500”是你独立压测优化的,还是团队成果你蹭着写?全程没“我负责XX模块”“解决了XX具体问题”,纯把技术文档里的术语扒下来凑字数,看着像“知道名词但没实际动手”的实习生抄的。 2. **短项目塞满超纲技术点,可信度直接***** IntelliDoc就干了5个月,又是RAG又是大模型流式响应又是RBAC权限,这堆活儿正经团队分工干都得小半年,你一个后端开发5个月能吃透这么多?明显是把能想到的技术全往里面塞,生怕别人知道你实际只做了个文件上传——这种“技术堆砌式造假”,面试官一眼就能看出水分。 3. **技能栏是“模糊词混子集合”,没半点硬核度** “熟悉HashMap底层”“了解JVM内存模型”——“熟悉”是能手写扩容逻辑?“了解”是能排查GC问题?全是模棱两可的词,既没对应项目里的实践,也没体现深度,等于白写;项目里用了Elasticsearch的KNN检索,技能栏里提都没提具体掌握程度,明显是“用过但不懂”的硬凑。 4. **教育背景和自我评价全是“无效信息垃圾”** GPA前10%这么好的牌,只列“Java程序设计”这种基础课,分布式、微服务这些后端核心课提都不提,白瞎了专业优势;自我评价那堆“积极认真、细心负责”,是从招聘网站抄的模板吧?没有任何和项目挂钩的具体事例,比如“解决过XX bug”“优化过XX性能”,纯废话,看完等于没看。 总结:这简历是“技术名词缝合怪+自我感动式凑数”,看着像“背了后端技术栈名词的应届生”,实则没干货、没重点、没可信度——面试官扫30秒就会丢一边,因为连“你能干嘛”都没说清楚。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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