D - Divisibility by 2^n
这道题的大概意思是通过对每一个位子上的数进行一个乘下标加一的操作使得乘机的值能被2的n次方整除,本质上的意思就是比较long2(a)和long2(i)的和与n的一个大小关系如果小于的话就是不行,如果大于等于的话就通过对1到n的累加,求小于n时的次数,cnt就是答案所解,样例代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int t;
cin>>t;
while(t--){
ll n,len=0,len1=0,len2,a,b[100];
cin>>n;
memset(b,0,sizeof(b));
// 2 0 1 1 1 2
for(int i=1;i<=n;i++){
cin>>a;
while(!(a%2)){
len++;
a/=2;
}
a=i;
len2=0;
while(!(a%2)){
len1++;
len2++;
a/=2;
}
b[len2]++;
}
if(len+len1<n){
cout<<-1<<endl;
}
else{
int cnt=0;
for(int i=99;i>0;i--){
while(b[i]){
if(len+i<=n){
len+=i;
b[i]--;
cnt++;
}
else break;
}
}
cout<<cnt<<endl;
}
}
}
E - Divisible Numbers (easy version)
遍历x+1~c,找a*b与x的最大最大公因数,得到k,y为(a*b)/k;
因为y>b,所以(y+b)/y*y = y,如果y<=d则成立
#include<iostream>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){
if(b==0){
return a;
}
return gcd(b,a%b);
}
int main(){
int t;
cin>>t;
while(t--){
ll a,b,c,d;
cin>>a>>b>>c>>d;
bool flag=true;
for(ll i=a+1;i<=c;i++){
ll k=gcd(a*b,i);
ll x=a*b/k;
x=b/x*x+x;
if(x<=d){
cout<<i<<" "<<x<<endl;
flag=false;
break;
}
}
if(flag)cout<<-1<<" "<<-1<<endl;
}
}