2022牛客寒假算法基础集训营4(C/D/I/J)

C-蓝彗星

构造查分数组并利用前缀和处理,注意右边界,遍历特定情况即可。

代码

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N=200010;
int red[N];int blue[N];
int r[N],b[N];

inline void solve(){
	int n,t;
    cin>>n>>t;
    string s;
    cin>>s;
    int maxx=0;
    int x;
    for(int i=0;i<n;i++){
        cin>>x;
        maxx=max(maxx,x);
        if(s[i]=='B'){
            blue[x]++;
            blue[x+t]--;
        }
        else if(s[i]=='R'){
            red[x]++;
            red[x+t]--;
        }
    }
    maxx+=t;
    for(int i=1;i<=N;i++){
        r[i]=r[i-1]+red[i];
        b[i]=b[i-1]+blue[i];
    }
    int sum=0;
    
    for(int i=1;i<=maxx;i++)
        if(b[i]!=0&&r[i]==0)
            sum++;

    cout<<sum;
}

signed main(){
	solve();
	return 0;
}

D-雪色光晕

万恶数学题,拥有公式即可。

代码

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-7; 
int n;
double x,y,a,b,tmpx,tmpy;
double ta,tb,tc,cob,coc,coa,p;
double F(double x1,double y1,double x2,double y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

double f(){
	ta=F(x,y,tmpx,tmpy);
	tb=F(a,b,x,y);
	tc=F(a,b,tmpx,tmpy);
	p=(ta+tb+tc);
	coa=(tb*tb+tc*tc-ta*ta)/(2*tb*tc);
	cob=(ta*ta+tc*tc-tb*tb)/(2*ta*tc);
	coc=(ta*ta+tb*tb-tc*tc)/(2*ta*tb);
	if((coc<=eps||cob<=eps)){
		return min(tb,tc);
	}
	else return sqrt(p*(tb+tc-ta)*(ta+tc-tb)*(tb+ta-tc))/(2*ta);
}
void solve(){
    cin>>n>>x>>y>>a>>b;
	double ans=sqrt((x-a)*(x-a)+(y-b)*(y-b));
	while(n--){
		cin>>tmpx>>tmpy;
		tmpx=tmpx+x;
		tmpy=tmpy+y;
		double minn=f();
        if(ans>minn)
            ans=minn;
        x=tmpx;
        y=tmpy;
	}
	printf("%.10lf",ans);
}

int main(){
	solve();
}

I-爆炸的符卡洋洋洒洒

相似题见:OpenJudge 2989 糖果

01 01 01背包题,由于最终需要取 k k k 的倍数,因此可转化为模数为 0 0 0 的形式。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1010;
int n,k,a[maxn],d[maxn][maxn],sum=0,b[maxn];
signed main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    	cin>>a[i]>>b[i];
    memset(d,-20,sizeof(d)); 
    for(int i=0;i<=n;i++)
        d[i][0]=0;
    for(int i=1;i<=n;i++)
    	for(int j=0;j<k;j++){
        	d[i][j]=d[i-1][j];
        	d[i][j]=max(d[i][j],d[i-1][(j-a[i]%k+k)%k]+b[i]);
    }
    if(d[n][0]==0)
        cout<<"-1"<<endl;
    else
        cout<<d[n][0]<<endl;
    return 0;
}

J-区间合数的最小公倍数

将区间内所有合数拆解为质因数并记录个数,若大于 m a p map map 中记录的个数则替换,最后暴力相乘即可。

代码

#include <bits/stdc++.h>
#define int long long
const int N=30050;
using namespace std;
int primes[N],cnt;
bool st[N];//合数 
const int mod=1000000007;

map<int,int> mp;

void get_primes(){
    for(int i=2;i<=N;i++){
        if(st[i]) continue;
        primes[cnt++]=i;
        for(int j=i+i;j<=N;j+=i)
            st[j]=true;
    }
}

inline void solve(){
	int l,r;
    cin>>l>>r;
    get_primes();
    if(r<=3){
    	cout<<"-1";return ;
	}
	if(l==r&&!st[l]){
		cout<<"-1";return ; 
	}
	for(int x=l;x<=r;x++){
		if(!st[x])
			continue;
        int xx=x;
		for(int i=2;i<=x/i;i++){
			int count=0;
			while(xx%i==0){
				xx/=i;
				count++;
			}
			if(count>mp[i])
				mp[i]=count;
		}
        if(xx!=0&&mp[xx]==0)
                mp[xx]++;
	}
	int sum=1;
	for(int i=1;i<=30000;i++){
		if(mp[i]!=0){
			for(int j=1;j<=mp[i];j++){
				sum=sum*i%mod;
			}
		}
	}
	cout<<sum;
}

signed main(){
	solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值