2021 7.24 模拟测试

【题目描述】

输入k1,k2,k3,a-i为一组,j-r为一组,s-z与_为一组,给一串字符串,要求将每组分别向前移动k为,问最终字符串

【输入格式】

第一行3个整数,K1,K2,K3
第二行为一行字符串,为只包含小写字母和’_’的

【输出格式】

一行,为解密后的文本

【输入样例】

2 3 1
_icuo_bfnwhoq_kxert

【输出样例】

the_quick_brown_fox

【数据规模】

输入字符串长度不超过80
1<=Ki<=100

题解

直接模拟即可,分别考虑三种情况,最后按序输出
注意k1,k2,k3都需要取模否则数组会爆,取模时要判断len是否为0,模数不可以为0

代码

#include<bits/stdc++.h>
using namespace std;
int k1,k2,k3,f1,f2,f3,t[100];
char a[11000],b[11000],c[11000];
string s;
int main()
{
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	scanf("%d%d%d",&k1,&k2,&k3);
	cin>>s;int len=s.size();
	for(int i=1;i<=len;i++)
	{
		if(s[i-1]>='a'&&s[i-1]<='i') a[++f1]=s[i-1],t[i]=0;
		else if(s[i-1]>='j'&&s[i-1]<='r') b[++f2]=s[i-1],t[i]=1;
		else if((s[i-1]>='s'&&s[i-1]<='z')||s[i-1]=='_') c[++f3]=s[i-1],t[i]=2;
	}
//	for(int i=1;i<=f1;i++) cout<<a[i];
//	cout<<"\n";
	k1=f1==0?k1:k1%f1;
	k2=f2==0?k2:k2%f2;
	k3=f3==0?k3:k3%f3;
	for(int i=1;i<=f1-k1;i++) a[f1+i]=a[i];
	for(int i=1;i<=f2-k2;i++) b[f2+i]=b[i];
	for(int i=1;i<=f3-k3;i++) c[f3+i]=c[i];
	f1=f1-k1,f2=f2-k2,f3=f3-k3;
	for(int i=1;i<=len;i++)
	{
		if(t[i]==0) printf("%c",a[++f1]);
		else if(t[i]==1) printf("%c",b[++f2]);
		else if(t[i]==2) printf("%c",c[++f3]);
	}
//	cout<<"\n"<<s<<"\n"<<len;
//	cout<<"\n";
//	for(int i=k1+1;i<=f1;i++) cout<<a[i];
	return 0;
}

描述

在信息竞赛班的一次欢乐活动中,为了增强友谊,同学们站成了一列,编号从1到n。每个人 手上都有一个球,球上有一个数字。游戏规定对于任意两个人(i,j),他们的友好度为(i-j)2+g(i,j)2,其中g(i,j)= ∑ jk=i+1a[k]
请你帮助老师计算出任意两个人的最小可能友好度是多少?

输入

第一行1个整数 接下来一行是N个整数,表示每个人手上球上的数字。

输出

输出 1个整数表示最小的友好度

输入样例

4
1 0 0 -1

输出样例

1

【数据规模和约定】

40%的数据保证:
100%的数据保证:

题解

正解

设s[i]为前缀和,g(i,j)即为sum[j]-sum[i]
问题变为求平面内最近点对
1、选取一垂直线l:x=m 来作为分割直线。其中 为 中各点x坐标的中位数。由此将S分割为S1和S2。
2、递归地在S1和S2上找出其最小距离d1和d2,并设d=min{d1,d2},S中的最接近点对或者是d,或者是某个{p,q},其中p∈P1且q∈P2。最后枚举区间间点对。

非正解

这个竟然可以n2,加一步剪枝即可
枚举每个点,若当前(i-j)2>ans,由于(sum[i]-sum[j])2>0
则直接停止搜索

代码

非正解

#include<bits/stdc++.h>
using namespace std;
#define pf(x,y) (x-y)*(x-y)
#define int long long
#define in read()
inline int read()
{
    int data=0;int w=1; char ch=getchar();
    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
    return data*w;
}
int n,a[100005],sum[100005],ans=1e18;
int dist(int x,int y)
{
	int ret=pf(x,y);
	if(ret>ans) return -1;
	return ret;
}
signed main()
{
	n=in;
	for(int i=1;i<=n;i++) a[i]=in,sum[i]=sum[i-1]+a[i];
	for(int i=1;i<n;i++)
		for(int j=i+1;j<=n;j++)
		{
			int ret=dist(i,j);
			if(ret==-1) break;
			int g=pf(sum[i],sum[j]);
			ans=min(ans,g+ret);
		}
	cout<<ans;
}

正解

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define in read()
inline int read()
{
    int data=0;int w=1; char ch=getchar();
    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
    return data*w;
}
const int N=1e5+10;
int q[N],k;
struct node{int x;ll y;}p[N];
bool cmp1(node a,node b){return a.x<b.x;}
bool cmp2(node a,node b){return a.y<b.y;}
ll dis2(int a,int b){return (ll)(p[a].x-p[b].x)*(p[a].x-p[b].x)+(ll)(p[a].y-p[b].y)*(p[a].y-p[b].y);}
ll solve(int l,int r)
{
	if(l==r)return 1e18;
	int mid=l+r>>1;
	ll d2=min(solve(l,mid),solve(mid+1,r));
	inplace_merge(&p[l],&p[mid+1],&p[r+1],cmp2);
	k=0;
	double d=sqrt(d2);
	for(int i=l;i<=r;++i)
		if(fabs(p[mid].x-p[i].x)<d)
			q[++k]=i;
	for(int i=1;i<=k;++i)
		for(int j=i+1;j<=k&&p[q[j]].y-p[q[i]].y<d;++j)
			d2=min(d2,dis2(q[i],q[j]));
	return d2;
}
signed main()
{
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	n=in;
	for(int i=1,w;i<=n;++i)
	{
		a[i]=in,sum[i]=sum[i-1]+a[i];
		p[i].x=i,p[i].y=p[i-1].y+a[i];
	}
		sort(p+1,p+n+1,cmp1);
		cout<<solve(1,n);
	return 0;
}
posted @ 2021-07-24 15:16  Socratize  阅读(47)  评论(0)    收藏  举报