2020-2-16赛

问题 G: Semi Common Multiple

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态]

题目描述

Given are a sequence A=a1,a2,......aN of N positive even numbers, and an integer M.
Let a semi-common multiple of A be a positive integer X that satisfies the following condition for every k(1≤k≤N):
There exists a non-negative integer p such that X=ak×(p+0.5).
Find the number of semi-common multiples of A among the integers between 1 and M (inclusive).

Constraints
·1≤N≤105
·1≤M≤109
·2≤ai≤109
·ai is an even number.
·All values in input are integers.

输入

Input is given from Standard Input in the following format:

N M
a1 a2... aN

输出

Print the number of semi-common multiples of A among the integers between 1 and M (inclusive).

样例输入 Copy

【样例1】
2 50
6 10
【样例2】
3 100
14 22 40
【样例3】
5 1000000000
6 6 2 6 2

样例输出 Copy

【样例1】
2
【样例2】
0
【样例3】
166666667

提示

样例1解释
15=6×2.5
15=10×1.5
45=6×7.5
45=10×4.5
Thus, 15 and 45 are semi-common multiples of A. There are no other semi-common multiples of A between 1 and 50, so the answer is 2.

 

看到这道题,其实就是找【0,m】内有多少个数能使A【k】(k属于【1,n】)为1.5、2.5、3.5........倍

最初想暴力找。。。

但是发现这道题应该是考察数学方面的知识;

然后就想到找最大公倍数。。。但是我写的太丑。。。。出现bug了

然后看了别人的gcd和lcm,

由于所有的A【k】都是even偶数,所以我第一遍就把A【k】/=2;因为找1.5、2.5、3.5.....倍,其实就变成了找(A【k】/2)的奇数倍。。。。。设B[k]=A[k]/2;

然后我们就找所有的B【k】的lcm,如果lcm>m return 0;

如果存在(lcm/B【k】)%2==0,这种情况,我们是无法得到B【k】的奇数倍的...这个时候return 0;

有个样例;

3 10

2,4,8

答案0;

//第一次错误代码。。。很多漏洞
​#include <bits/stdc++.h>
using namespace std;
const int mod=1e5+5;
typedef long long ll;
int A[mod];
int main()
{
    int n,m,maxn=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        {
            scanf("%d",&A[i]);
            A[i]/=2;
            maxn=max(maxn,A[i]);
        }
    int sum=1;
    for(int i=1;i<=n;i++)
    {
        if(sum%A[i]==0) continue;
        else
        {
            int temp=sum,t=A[i];
           while(t)//temp/t
           {
               int a=t;
               t=temp%t;
               temp=a;
           }
           sum*=A[i]/temp;
        }
        if(sum>m)
        {
            printf("0");
            return 0;
        }
    }
//    printf("maxn:%d\n",maxn);
//    printf("sum:%d\n",sum);
    int ans=0;
    for(int i=1;;i+=2)
    {
        if(sum*i<=m) ans++;
        else break;
    }
     printf("%d",ans);
 
    return 0;
}
 
/**************************************************************
    Problem: 14611
    User: 2019UPC110
    Language: C++
    Result: 时间超限
****************************************************************/​

 看看别人那偷的gcd和lcm,学着点。。。。。。。

//借鉴了别人的gcd和lcm的写法
#include <bits/stdc++.h>
using namespace std;
const int mod=1e5+5;
typedef long long ll;
ll A[mod];
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int main()
{
    ll n,m,maxn=0,sum=0;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
        {
            scanf("%lld",&A[i]);
            A[i]/=2;
            if(i==1) sum=A[1];
            sum=lcm(sum,A[i]);
        }
    if(sum>m)
        {
            printf("0");
            return 0;
        }
    for(int i=1;i<=n;i++)
    {
        if(sum/A[i]%2==0)
        {
            printf("0");
            return 0;
        }
    }
//    printf("maxn:%d\n",maxn);
//    printf("sum:%d\n",sum);
    int ans=m/sum;
    if(ans%2==1) ans=ans/2+1;
    else ans/=2;
     printf("%d",ans);
 
    return 0;
}
 
/**************************************************************
    Problem: 14611
    User: 2019UPC110
    Language: C++
    Result: 正确
    Time:50 ms
    Memory:2804 kb
****************************************************************/

 

 

问题 J: Times 17

时间限制: 1 Sec  内存限制: 64 MB
[提交] [状态]

题目描述

After realizing that there is much money to be made in software development, Farmer John has launched a small side business writing short programs for clients in the local farming industry.   

Farmer John's first programming task seems quite simple to him -- almost too simple: his client wants him to write a program that takes a number N as input, and prints 17 times N as output.  Farmer John has just finished
writing this simple program when the client calls him up in a panic and informs him that the input and output both must be expressed as binary numbers, and that these might be quite large.

Please help Farmer John complete his programming task.  Given an input number N, written in binary with at most 1000 digits, please write out the binary representation of 17 times N.

输入

* Line 1: The binary representation of N (at most 1000 digits).

输出

* Line 1: The binary representation of N times 17.

样例输入 Copy

10110111

样例输出 Copy

110000100111

提示

The binary number 10110111 is equal to 183 in decimal form. 183×17 = 3111 is 110000100111 in binary format.

 

第一次的暴力法:把2进制变成10进制再乘17,然后再把它按2进制输出。

哎,漏洞这么明显。。。。。。我也无语了

//虽说是运行错误,但把范围扩大,会数据溢出导致答案错误。。。。
#include <bits/stdc++.h>
using namespace std;
const int mod=1e5+5;
typedef long long ll;
 
int main()
{
    char str[105];
    scanf("%s",str);
    int len=strlen(str);
    ll temp=1,ans=0;
    for(int i=len-1;i>=0;i--)
    {
        ans+=(str[i]-'0')*temp;
        temp*=2;
        //printf("ans:%lld\ntemp:%lld\n",ans,temp);
    }
   ans=17*ans;
   vector<int>q;
   while(ans)
   {
       q.push_back(ans%2);
       ans/=2;
   }
     int si=q.size();
     for(int i=si-1;i>=0;i--)
        printf("%d",q[i]);
      return 0;
}
 
/**************************************************************
    Problem: 2519
    User: 2019UPC110
    Language: C++
    Result: 运行错误
****************************************************************/

自然就想会不会是2进制和2进制相乘呢??

大概看了一下别人的思路

就是这样的

于是自己就写了下

heiheihei

用上了上次学到的reverse

虽然又忘了reserve的写法,不过思路很清楚,

知道哪些知识可以用。。。。

 

 

#include <bits/stdc++.h>
using namespace std;
const int mod=1e5+5;
typedef long long ll;
vector<int>A,B;
//用二进制模拟十进制乘法17=10001;
int main()
{
    string a,b;
    cin>>a;
    b=a+"0000";
    int lena=a.length(),lenb=b.length();
    for(int i=0; i<lena; i++)
       A.push_back(a[i]-'0');
    for(int i=0; i<lenb; i++)
       B.push_back(b[i]-'0');
       reverse(A.begin(),A.end());
       reverse(B.begin(),B.end());
       for(int i=1;i<=5;i++)
        A.push_back(0);
       B.push_back(0);
//    for(int i=0;i<lenb;i++)
//        printf("%d",A[i]);
//        puts("");
//    for(int i=0;i<lenb;i++)
//        printf("%d",B[i]);
//        puts("");
    for(int i=0;i<lenb;i++)
    {
        int temp=B[i];
        B[i]=(A[i]+temp)%2;
        B[i+1]+=(A[i]+temp)/2;
    }
    if(B[lenb]==2) printf("10");
    else if(B[lenb]==1) printf("1");
    for(int i=lenb-1;i>=0;i--)
        printf("%d",B[i]);
 
    return 0;
}
 
/**************************************************************
    Problem: 2519
    User: 2019UPC110
    Language: C++
    Result: 正确
    Time:1 ms
    Memory:2028 kb
****************************************************************/

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值