A. Coin Transformation
算法:模拟 枚举
思路:记录当前每个硬币大小 当每个硬币大小大于3时候 将硬币个数翻倍 再将每个硬币大小除以四 枚举直到硬币大小小于3时 输出硬币个数
代码:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9+7;
ll a[Q];
void solve(){
ll n;cin>>n;
ll ans=1;
while(n>3){
n/=4;
ans*=2;
}
cout<<ans<<"\n";
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
ll _ = 1;cin>>_;
while(_--){
solve();
}
return 0;
}
B. Digits
算法:打表
思路:打表 找出1到18个每个不同数字并列时在多少个的时候可以整除 3和7和9。
1:所有数都可以被1整数。
3:当该数字个数为3的倍数的时候 或者 该数字可以整除3的时候则符合条件(3,6,9)
5:必须当该数为5的时候则符合条件
7:若该数为7则符合条件
当该数不为7 该数字个数为6的倍数的时候则符合条件
9:若该数为9则符合条件
若该数为3或者6的时候 该数字个数为3的倍数即可
若该数不为3或6或9的时候 该数字个数为9的倍数即可
代码:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9+7;
void solve(){
ll n,d;cin>>n>>d;
cout<<1<<" ";
if(n>=3 or d%3==0){
cout<<3<<" ";
}
if(d==5){
cout<<5<<" ";
}
if(n>=3 or d==7){
cout<<7<<" ";
}
if((n>=6 or d==9) or (n>=3 and (d==3 or d==6))){
cout<<9<<" ";
}
cout<<"\n";
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
ll _ = 1;cin>>_;
while(_--){
solve();
}
return 0;
}
C. Sums on Segments
算法:前缀和
思路:找出不为1和-1的数的位置为it 然后将该数组分成两部分,分别求出左边和右边的最小字段和 和最大字段和 然后将最小值到最大值 全部加入答案,然后从it位置 往左右两边跑 找出往左边走的最大前缀和与最小前缀和 往右边走的最大前缀和和最小前缀和。然后将it位置的数字加入左右两边的最小值 还有最大值 然后将这个最小值到最大值区间加入答案
代码:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9+7;
ll a[Q];
set<ll> an;
void solve(){
ll n;cin>>n;
ll it=0;
for (ll i = 1; i <= n; i++){
cin>>a[i];
if(a[i]!=-1 and a[i]!=1) it=i;
}
an.clear();
an.insert(0);
ll mx=0;
ll now=0;
ll ans=0;
for (ll i = 1; i < it; i++)
{
now+=a[i];
mx=min(mx,now);
ans=max(ans,now-mx);
}
for (ll i = 0; i <= ans; i++)
{
an.insert(i);
}
mx=0;
now=0;
ans=0;
for (ll i = 1; i < it; i++)
{
now+=a[i];
mx=max(mx,now);
ans=min(ans,now-mx);
}
for (ll i = 0; i >= ans; i--)
{
an.insert(i);
}
mx=0;
now=0;
ans=0;
for (ll i = it+1; i <= n; i++)
{
now+=a[i];
mx=min(mx,now);
ans=max(ans,now-mx);
}
for (ll i = 0; i <= ans; i++)
{
an.insert(i);
}
mx=0;
now=0;
ans=0;
for (ll i = it+1; i <= n; i++)
{
now+=a[i];
mx=max(mx,now);
ans=min(ans,now-mx);
}
for (ll i = 0; i >= ans; i--)
{
an.insert(i);
}
ll sum=0;
ll rmax=0,rmin=0;
ll lmax=0,lmin=0;
for (ll i = it+1; i <= n; i++)
{
sum+=a[i];
rmax=max(rmax,sum);
rmin=min(rmin,sum);
}sum=0;
for (ll i = it-1; i >= 1; i--)
{
sum+=a[i];
lmax=max(lmax,sum);
lmin=min(lmin,sum);
}
for (ll i = a[it]; i >= a[it]+lmin+rmin; i--)
{
an.insert(i);
}
for (ll i = a[it]; i <= a[it]+lmax+rmax; i++)
{
an.insert(i);
}
// cout<<lmin<<" "<<rmin<<"\n";
// cout<<lmax<<" "<<rmax<<"\n";
cout<<an.size()<<"\n";
for(auto i:an) cout<<i<<" ";
cout<<"\n";
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
ll _ = 1;cin>>_;
while(_--){
solve();
}
return 0;
}
D. Problem about GCD
算法:枚举
思路:找出的A和B肯定能被G所整除 所以A可以写成 G*a , B是G*b,为了使得|A-B|最大 也就是让|a-b|也最大,为了让A和B的GCD=G 也就是让a和b的GCD=1即可,a和b的GCD等于1后 则A和B就只能被G所整除了,先把l靠近比它大的能被G所整除的数 r靠近比它小的能被G所整除的数 然后转换成l/G 和 r/G,然后先枚举长度 再枚举起点a的位置,暴力判断a和b是否gcd为1不是则更新起点 然后再更新长度,两个质数之间的距离log(1e18)所以枚举次数不会太多。
代码:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9+7;
ll a[Q];
void solve(){
ll l,r,g;cin>>l>>r>>g;
l=(l/g+!!(l%g))*g;
r=(r/g)*g;
ll o=l/g,p=r/g;
for (ll i = p-o ; i >= 0; i--)
{
for (ll j = o; j <= p; j++)
{
if(j+i>p) break;
if(gcd(j,j+i)==1){
cout<<j*g<<" "<<g*(j+i)<<"\n";
return;
}
}
}
cout<<"-1 -1\n";
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
ll _ = 1;cin>>_;
while(_--){
solve();
}
return 0;
}
1309

被折叠的 条评论
为什么被折叠?



