牛客挑战赛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<bits/stdc++.h>
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("%lld\n",c[i]*a);
                break;
            }
    }
}

B:

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

代码如下:

#include<bits/stdc++.h>
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 %.1lf\n",(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("NO\n");
    }
}

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<bits/stdc++.h>
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<<f[n];
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值