A.注意判断一下9和1;
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;scanf("%d%d",&a,&b);
if(a==9 && b==1) printf("9 10\n");
else if(b-a>=2 || a>b) printf("-1\n");
else if(b-a==1) printf("%d %d\n",a*10+9,b*10);
else if(a==b) printf("%d %d\n",a*10,b*10+1);
return 0;
}
B.左右两个指针判断加减,记录当前区间内数字种类数,更新取最小
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
int a[maxn];
map<int,int> num;
void rua()
{
num.clear();
int n,k,d;scanf("%d%d%d",&n,&k,&d);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int ans=0;
for(int i=1;i<=d;i++)
{
if(!num[a[i]]) ans++;
num[a[i]]++;
}
int pos=0,res=ans;
for(int i=d+1;i<=n;i++)
{
num[a[++pos]]--;
if(num[a[pos]]==0) res--;
if(num[a[i]]==0) res++;
num[a[i]]++;
ans=min(ans,res);
}
printf("%d\n",ans);
}
int main()
{
int t;scanf("%d",&t);
while(t--) rua();
return 0;
}
C.枚举答案,check当前i判断是否可行,当前n-i*p可以构造出的下界为二进制下1的个数,上界为它本身;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool check(ll x,int num)
{
ll res=x;int kk=0;
while(res)
{
if(res%2==1) kk++;
res/=2;
}
return kk<=num;
}
int rua()
{
ll n;int p;scanf("%lld%d",&n,&p);
for(int i=1;i<=31;i++)
{
ll x=n-p*i;
if(x<=0) continue;
if(check(x,i) && x>=i) return i;
}
return -1;
}
int main()
{
printf("%d\n",rua());
return 0;
}
D.对每个数质因数分解,然后幂次%k,找另一半的个数;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=2e5+7;
int prime[maxn],vis[maxn];
int tot;
ll a[maxn],b[maxn],c[maxn];
//a[i]这个数本身 b[i]这个数的底数之积 c[i]这个数每个质因子的幂次%k后的积
std::vector<ll> v[maxn];//第i个数的质因子
std::map<ll,ll> mp;
void getprime()
{
for(int i=2;i<maxn;i++)
{
if(!vis[i]) prime[++tot]=i;
for(int j=1;j<=tot,i*prime[j]<maxn;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
int main()
{
getprime();
int n,k;scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
ll x;scanf("%lld",&x);
a[i]=x;b[i]=1;c[i]=1;
for(int j=1;j<=tot,1ll*prime[j]*prime[j]<=x;j++)
{
if(x%prime[j]==0)
{
int kk=0;
b[i]*=prime[j];
while(x%prime[j]==0) x/=prime[j],kk++;
kk%=k;
while(kk--) c[i]*=prime[j];
v[i].pb(prime[j]);
}
}
if(x!=1) b[i]*=x,c[i]*=x;
}
ll ans=0;
for(int i=1;i<=n;i++)
{
ll tmp=1;bool flag=true;
for(int j=1;j<=k;j++)
{
tmp*=b[i];
if(tmp>(ll)1e11) {flag=false;break;}
}
if(flag)
{
ll res=tmp/c[i];
for(auto j:v[i])//因为之前%过 所以可能c[i]中质因子的幂次变成0 这里排除影响
{
ll kk=res;int cnt=0;
while(kk%j==0) kk/=j,cnt++;
if(cnt==k) res=kk;
}
if(mp.count(res)) ans+=mp[res];
}
mp[c[i]]++;
}
printf("%lld\n",ans);
}