问题 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
****************************************************************/