UCF Local Programming Contest Round 1A(C,D,E题解)

CUnique Values

题意:给定字符串,求所有不包含重复元素的子串,位置不同也算不同。

思路:

借鉴某大佬得出的一种时间复杂度相对好点的方法,从第一个元素一个一个放进deque,用map记录次数,当有2次时对前面的重复元素剔除到无重复元素,每次加上q.size()(这里表示每个子串的个数,细想下就是这样的规律);

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<string.h>
#include<vector>
#include<map>
#include<deque> 
using namespace std;
typedef long long ll;
const int N=1e5+100;
ll a[N];
map<ll,ll>cnt;
deque<ll>q;
int main(){
	int n;
	ll sum=0;
	cin>>n;	
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
    for(int i=0;i<n;i++){
       if(cnt[a[i]]==0)
	   {
	   	cnt[a[i]]++;
        q.push_back(a[i]);
	   }
       else {
       	cnt[a[i]]++;
        q.push_back(a[i]);
       	while(!q.empty()&&cnt[a[i]]>=2){
       		cnt[q.front()]--;
       		q.pop_front();
		   } 
	   } 	    
	   sum+=q.size();
	}
	printf("%lld",sum);
} 

D题:Gone Fishing

题意:给定圆的半径与点的个数与坐标,求圆最多能覆盖多少点

思路:枚举法,数字不是很大,可以试试暴力枚举,通过两个点求出圆心坐标,之后对剩余的点求距离小于给定半径即++;(这种题确实没想到别的办法,只能说题做少了,人家一下就看出来,我===)

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<string.h>
#include<vector>
#include<map>
#include<cmath>
#include<deque> 
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
const int N=210;
const double eps=1e-6;
struct node{
	double x,y;
}p[N];
double cal(node a,node b){
	double xm=a.x-b.x,ym=a.y-b.y;
	return sqrt(xm*xm+ym*ym);
}
node get_center(node m,node n,int r){
	node mid={(m.x+n.x)/2,(m.y+n.y)/2};
	double angle=atan2(m.x-n.x,n.y-m.y);
	double d=sqrt(r*r-pow(cal(mid,m),2));
	return {mid.x+d*cos(angle),mid.y+d*sin(angle)};
}
int main(){
	int n,r;
	cin>>r>>n;
	for(int i=1;i<=n;i++)cin>>p[i].x>>p[i].y;
	int ans=1,maxx;
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			if(cal(p[i],p[j])>2.0*r)continue;
			node cen=get_center(p[i],p[j],r);
            maxx=0;
			for(int k=1;k<=n;k++){
				if(cal(p[k],cen)<1.0*r+eps)maxx++;				
			}
			ans=max(ans,maxx);
		}
	}
	cout<<ans<<endl;
} 

E题Sum of a Function

题意:给定s到e个数需要求出前k小的每个数最小素因数的和;

、思路:常规思路求最下素因数肯定爆 ,因为范围是1e18,还有这里可以不要开太大的数组,开e-s范围的数组,把数组下标减去s存储大数,对于已经读过的数可以用if(!f[i])f[i]=xx,来避免6的素因子为3这种情况,筛的思路是用欧拉筛去筛,从2开始到k个结束

ps:小知识获得:for循环时避免每次进行大数计算判断会很浪费时间,可以改用一开始计算,之后每次只需判断,减少时间的浪费,(我的超时就是这个小细节)。

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<string.h>
#include<vector>
#include<map>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
typedef long long ll;
const int N=1e6+1000;
bool  vis[N];
ll p[N],f[N];
ll s,e,k,cnt,sum=0;
void oula(){
	for(int i=2;i<N;i++){
		if(vis[i]==0)p[++cnt]=i;
		for(int j=1;j<=cnt&&p[j]*i<N;j++){
			vis[p[j]*i]=1; 			
			if(i%p[j]==0)break;
		}
	}
}
void solve(ll l,ll r){
	for(int i=0;i<r-l+1;i++)f[i]=i+l;
	for(int i=1;i<=cnt;i++)
	{
	   ll s=l/p[i];
	   if(s<=1)s=1;
	   for(ll j=s*p[i];j<=r;j+=p[i]){
	   	if(j>=l){
	   		if(f[j-l]==j)f[j-l]=p[i];
		   }
	   }	
	}
}
int main(){   
   oula();	 
   cin>>s>>e>>k;
   solve(s,e);
   sort(f,f+e-s+1);
   for(int i=0;i<k;i++){
   	sum+=f[i];
   }
     cout<<sum<<endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值