Acwing第 54 场周赛【完结】

最近很忙,周赛一般都是随便打的。
T2wa了好久,做完T2就吃饭去了。

在这里插入图片描述
短暂的高光。。。

4428. 字符串【签到】

#include<bits/stdc++.h>
using namespace std;
int n;
string s;
map<char,int>mp;
int main(void)
{
    cin>>n>>s;
    for(int i=0;i<s.size();i++)
    { 
        s[i]=tolower(s[i]);
        if(s[i]>='a'&&s[i]<='z') mp[s[i]]++;
    }
    if(mp.size()==26) puts("YES");
    else puts("NO");
    return 0;
}

4429. 无线网络【思维 / 二分】

在这里插入图片描述
正解是O(nlogn),我一看想到了O(n*n log n) 的做法。最后卡了一个特殊的值,卡了好久才发现。
我的想法是处理出各个点到这两个站点的距离,枚举一个站点的半径,二分另一个站点的半径。

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
typedef long long int LL;
LL n,xx1,yy1,xx2,yy2;
LL x[N],y[N],len1[N],len2[N];
LL get(LL x,LL y,LL xx,LL yy)
{
	return (x-xx)*(x-xx)+(y-yy)*(y-yy);
}
bool check(LL s1,LL s2)
{
	for(int i=1;i<=n;i++)
		if(s1<len1[i]&&s2<len2[i]) return false;
	return true;
}
int main(void)
{
	cin>>n>>xx1>>yy1>>xx2>>yy2;
	LL maxv=-1e9;
	for(int i=1;i<=n;i++)
	{
		cin>>x[i]>>y[i];
		len1[i]=get(xx1,yy1,x[i],y[i]);
		len2[i]=get(xx2,yy2,x[i],y[i]);
		maxv=max(maxv,len2[i]);
	}
	LL ans=1e18;
	for(int i=0;i<=n;i++)
	{
		LL l=0,r=maxv;
		while(l<r)
		{
			LL mid=(l+r)/2;
			if(check(len1[i],mid)) r=mid;
			else l=mid+1;
		}
		ans=min(ans,len1[i]+l);
	}
	cout<<ans;
	return 0;
}

你会发现一个点的半径确定了,那个另一个点的半径就是没有覆盖的点到这个点的最大距离。
O(n*n)的做法。

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
typedef long long int LL;
LL n,xx1,yy1,xx2,yy2;
LL x[N],y[N],len1[N],len2[N];
LL get(LL x,LL y,LL xx,LL yy)
{
	return (x-xx)*(x-xx)+(y-yy)*(y-yy);
}
int main(void)
{
	cin>>n>>xx1>>yy1>>xx2>>yy2;
	for(int i=1;i<=n;i++)
	{
		cin>>x[i]>>y[i];
		len1[i]=get(xx1,yy1,x[i],y[i]);
		len2[i]=get(xx2,yy2,x[i],y[i]);
	}
	LL ans=1e18;
	for(int i=0;i<=n;i++)
	{
		LL temp=0;
		for(int j=1;j<=n;j++) if(len1[i]<len1[j]) temp=max(temp,len2[j]);
		ans=min(ans,len1[i]+temp);
	}
	cout<<ans;
	return 0;
}

可以排序后进一步的优化,线性的处理参考y总的做法。这里懒的写了。

4430. 括号序列【思维】

在这里插入图片描述
通过分析不难发现有两种情况:

  • 一种是左括号的数量多余右括号2个。
  • 一种是右括号的数量多余左括号2个。

我们只讨论右括号的数量多余左括号2个这种情况,另一种情况直接做镜像一样处理即可。

#include<bits/stdc++.h> 
using namespace std;
int n,l,r;
string s;
int main(void)
{
	cin>>n>>s;
	for(int i=0;i<s.size();i++)
		if(s[i]=='(') l++;
		else r++;
	if(abs(l-r)!=2) puts("0");
	else
	{
		if(l>r)
		{
		 	reverse(s.begin(),s.end());
		 	for(int i=0;i<s.size();i++) 
			 	if(s[i]=='(') s[i]=')';
			 	else s[i]='(';
		}
		int index=0,ans=0;
		l=0,r=0;
		for(int i=0;i<s.size();i++)
		{
			if(s[i]=='(') l++,index++;
			else r++,index--;
			if(index<0)//说明右括号多余左括号
			{
				ans=r;
				index=i+1;
				l++,r--;
				break;
			}
		}
		for(int i=index;i<s.size();i++)//判断翻转后的剩余的是否合法。
		{
			if(s[i]=='(') l++;
			else r++;
			if(r>l) ans=0;
		}
		cout<<ans;
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值