暑假周测题解1

1.幸运数字

题目:

image

分析:

这道题目N最大是\(2^{60}\),不会超过long long,\(log_4N\)最多也只有30,我们只需要每次给N除以4除以7就好了。

程序:

#include<bits/stdc++.h>
using namespace std;
long long n,ans1,ans2;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	while(n%4==0)
	{
		n=n/4;
		ans1++;
	}
	while(n%7==0)
	{
		n=n/7;
		ans2++;
	}
	cout<<ans1<<" "<<ans2<<'\n';
	return 0;
}

2.配对

题目:

给你两个序列A和B,都有n个数。然后从A、B中各选一个数让他们一一配对(不能重复,有n个配对),使得所有配对元素差的绝对值之和最大。

题目条件:

1.对于全部的数据,有\(n<=10000,a_i,b_i<=1000。\)

分析:

这道题目很明显,越小的和越大的相减的绝对值就更大,那么一个从大到小排序,一个从小到大排序,两两相减就可以了。

程序:

#include<bits/stdc++.h>
using namespace std;
int n,ans,a[10001],b[10001];
int cmp(int x,int y)
{
	return x>y;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<=n;i++)
		cin>>b[i];
	sort(a+1,a+n+1);
	sort(b+1,b+n+1,cmp);
	for(int i=1;i<=n;i++)
		ans+=abs(a[i]-b[i]);
	cout<<ans<<endl;
	return 0;
}

3.队形变换

题目:

在集体展演中,站位转换是核心要素。艺术节揭幕式上,策划人员设计了两类摆位方案:连续式(代码1)与交错式(代码2)。每类方案可依横排(代码1)或竖排(代码2)方式布局。为协助表演者准确找位,需要开发一款定位系统,该系统接收演出人数N、摆位类型X、排列类型Y、每条线上的最大容量R以及特定演员编码M作为变量,计算并提示该演员在整体阵容中的精确位置坐标(具体到第几排第几列)。以16人组合为范例,不同布局呈现效果可见如下:
1:N=16,X=1,Y=1,R=6

1  2  3  4  5  6
7  8  9  10 11 12
13 14 15 16

2: N=16,X=1,Y=2,R=3

1 4 7 10 13 16
2 5 8 11 14
3 6 9 12 15

3: N=16,X=2,Y=1,R=7

1  2 3  4
 5  6  7
8  9 10 11
 12 13 14
15 16

4: N=16,X=2,Y=2,R=6

1 7 13
 4 10 16
2 8 14
 5 11
3 9 15
 6 12

如输入16 1 1 6 12,则输出2 6。
如输入16 1 2 3 12,则输出3 4。
如输入16 2 1 7 12,则输出4 2。
如输入16 2 2 6 12,则输出6 4。

题目条件:

1.\(1<=N<=10000。\)

分析:

这道题需要分类讨论4种情况。

  1. X=1,Y=1
    行数为M/R向上取整,列数为M模R的余数,如果余0则是R。
  2. X=1,Y=2
    行数为情况1的列数,列数为情况1的行数。
  3. X=2,Y=1
    行数为M/R向下取整再乘上2,接下来如果M模R的余数大于0,则行数加1,如果M模R的余数大于R/2向上取整,则行数加1。
    如果M模R的余数为0,则列数为R/2向下取整再乘上2,否则,设变量t=1,如果M模R的余数大于等于R除以2向上取整,则把M模R,再减去R除以2向上取整,并且把t变为0。如果此时的M等于0,则列数为R除以2向上取整乘上2再减去t,否则列数为此时的M乘上2再减去t。
  4. X=2,Y=2
    行数为情况3的列数,列数为情况3的行数。

程序:

#include<bits/stdc++.h>
using namespace std;
int n,x,y,r,m;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>x>>y>>r>>m;
	if(x==1)
	{
		if(y==1)
		{
			cout<<(m+r-1)/r<<" ";
			if(m%r==0)
				cout<<r<<'\n';
			else
				cout<<m%r<<'\n';
		}
		else
		{
			if(m%r==0)
				cout<<r<<" ";
			else
				cout<<m%r<<" ";
			cout<<(m+r-1)/r<<'\n';
		}
	}
	else
	{
		if(y==1)
		{
			int p=(m/r)*2;
			if(m%r>0)
				p++;
			if(m%r>ceil(r/2.0))
				p++;
			cout<<p<<" ";
			m=m%r;
			if(m==0)
				cout<<r/2*2<<'\n';
			else
			{
				int t=1;
				if(m>=ceil(r/2.0))
				{
					m-=ceil(r/2.0);
					t=0;
				}
				if(m==0)
					cout<<int(ceil(r/2.0))*2-t<<'\n';
				else
					cout<<m*2-t<<'\n';
			}
		}
		else
		{
			int k=m;
			m=m%r;
			if(m==0)
				cout<<r/2*2<<'\n';
			else
			{
				int t=1;
				if(m>=ceil(r/2.0))
				{
					m-=ceil(r/2.0);
					t=0;
				}
				if(m==0)
					cout<<int(ceil(r/2.0))*2-t<<" ";
				else
					cout<<m*2-t<<" ";
			}
			int p=(k/r)*2;
			if(k%r>0)
				p++;
			if(k%r>ceil(r/2.0))
				p++;
			cout<<p<<'\n';
		}
	}
	return 0;
}

4.青铜莲花池

题目:

为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘。这个长方形的池子被分成了M行N列个方格\((1<=M,N<=30)\)。一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是美丽、纯净、湛蓝的水。贝西正在练习芭蕾舞,她站在一朵莲花上,想跳到另一朵莲花上去,她只能从一朵莲花跳到另一朵莲花上,既不能跳到水里,也不能跳到岩石上。贝西的舞步很像象棋中的马步:每次总是先横向移动\(M1(1<=M1<=30)\)格,再纵向移动\(M2(1<=M2<=30)\)格,或先纵向移动M1格,再横向移动M2格。最多时,贝西会有八个移动方向可供选择。给定池塘的布局和贝西的跳跃长度,请计算贝西从起点出发,到达目的地的最小步数,我们保证输入数据中的目的地一定是可达的。

题目条件:

1.池塘状态:0为水,1为莲花,2为岩石,3为贝西所在的起点,4为贝西想去的终点。

分析:

这道题目求的是最短路径,并且数据范围较小,我们有两种方法,一种是深度优先遍历,一种是宽度优先,本质上都是暴力枚举,不过深度优先遍历在这里感觉时间复杂度没有宽搜那么健康,所以我在比赛时用了一个宽搜程序,这道题目还是比较简单,相当于模板题。

程序:

#include<bits/stdc++.h>
using namespace std;
int m,n,m1,n1,a[31][31],b[31][31];
struct dd
{
	int x,y,step;
} q[1001];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>m>>n>>m1>>n1;
	int dx[8]={-m1,m1,m1,-m1,n1,-n1,n1,-n1};
	int dy[8]={n1,-n1,n1,-n1,-m1,m1,m1,-m1};
	for(int i=1;i<=m;i++)
		for(int j=1;j<=n;j++)
		{
			cin>>a[i][j];
			if(a[i][j]==3)
			{
				q[1].x=i;
				q[1].y=j;
			}
		}
	int l=1,r=1;
	while(l<=r)
	{
		for(int i=0;i<8;i++)
		{
			int tx=q[l].x+dx[i];
			int ty=q[l].y+dy[i];
			if(tx<1||ty<1||tx>m||ty>n||a[tx][ty]==0||a[tx][ty]==2||b[tx][ty])
				continue;
			r++;
			b[tx][ty]=1;
			q[r].x=tx;
			q[r].y=ty;
			q[r].step=q[l].step+1;
			if(a[tx][ty]==4)
			{
				cout<<q[r].step<<'\n';
				return 0;
			}
		}
		l++;
	}
	return 0;
}
posted @ 2026-07-27 10:51  zhhhanry  阅读(22)  评论(0)    收藏  举报