栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

牛客挑战赛60 ABC题解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

牛客挑战赛60 ABC题解

笔者能力有限,目前就补了abc。

A:

对于

  • c 是 a 的倍数,且 c>a。
  • gcd(a,b)=gcd(b,c)。

对于这两个条件,打破了笔者想着只要等于a就可以的小心思。。。毕竟这不是小白赛。所以我们可以开始先把第二个条件变成:a和b已经互质,而且b和c也互质,而且c是a的倍数。为什么可以这样变化呢,因为我们可以两边同除原gcd(a,b)的值,让他们都变成互质,即设u=gcd(a,b)。

gcd(a/u,b/u)=gcd(b/u,c/u)成立,那么我们可以很容易得知c/a的倍数与b也是互质,不然的话这个gcd不会为1,那么我们的条件就变成了只要找到能够与b/u互质的最小数字就行了。那么,代码如下:

#include
using namespace std;
#define int long long
int c[20]={2,3,5,7,11,13,17,19,23,29,31,37,41};//为什么只要到41呢,因为到41的连乘已经比1e14大
int d[100];
signed main(){
    int t;
    cin>>t;
    while(t--){
        int a,b;
        cin>>a>>b;
        int u=__gcd(a,b);
        b/=u;
        for(int i=0;i<=12;i++)
            if(b%c[i]!=0){
                printf("%lldn",c[i]*a);
                break;
            }
    }
}

B:

如果想知道解法的话,那么去看牛客的题解,他会很明确的告诉你就是一个普通的很暴力的暴力。就是点对们相加看看这个值会不会出现第二次。为什么可以这么做呢,为什么这样做时间复杂度不会超时呢?很简单的一个想法,因为我们把点对全部都加起来的话,总共可能出现的值只有可能是4*n*m个,不然的话就会出现新的覆盖点,被覆盖了我们就可以提前终止了。

代码如下:

#include
using namespace std;
#define int long long
int mp[2005][2005];
struct node{
    int x,y;
}a[100005];
signed main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n,m,k;
        cin>>n>>m>>k;
        for(int i=1;i<=2*n;i++)
            for(int j=1;j<=2*m;j++)
                mp[i][j]=0;
        for(int i=1;i<=k;i++)
            cin>>a[i].x>>a[i].y;
        int flag=0;
        for(int i=1;i<=k;i++){
            for(int j=i+1;j<=k;j++){
                if(mp[a[i].x+a[j].x][a[i].y+a[j].y]){
                    flag=1,printf("YES %.1lf %.1lfn",(a[i].x+a[j].x)*1.0/2,(a[i].y+a[j].y)*1.0/2);
                    break;
                }
                mp[a[i].x+a[j].x][a[i].y+a[j].y]=1;
            }
            if(flag)
                break;
        }
        if(flag==0)
            printf("NOn");
    }
}

C:

当你位于第 x个格子时,你可以进行以下两种操作:

  1. 走到第 x+1 个格子。
  2.  如果第 x 个格子未被染上色,把第 x 个格子染成黑色,然后跳到第 Ai​ 个格子。

对于一段区域即1-x(1<=x<=n)

如果最后落脚点是x的话,那么我们可能的转移方向就是从第x-1个转移过来的,没有意外。

如果最后落脚点不是x的话,我们可以选择Ax-(x-1)的任意一个数字作为最终落脚点,为什么呢,因为Ax到x-1这几个地方都可以由最后一个数字跳到Ax之后用1操作执行。

因为1-x这一段我们总共有f[x-1]*(x-Ax+1)种方法跳

因为1-1的时候,只能选择跳1,所以没地方跳,因此它的次数是1次,因此可以先进行初始化

代码如下:

#include
using namespace std;
#define int long long
int a[1000005];
int f[1000005];
int p=1e9+7;
signed main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    f[1]=1;//如果说只有1个的话,那肯定是只能移动一次
    for(int i=2;i<=n;i++){
        f[i]=f[i-1]*(i-a[i]+1)%p;
    }
    cout< 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/887434.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号