Codeforces Round #596 (Div.2)

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);
}

猜你喜欢

转载自blog.csdn.net/qq_43813163/article/details/102785182