河西-8.2上午3教室-廖

最后更新于 2025-08-03 12:55:48
分类 个人记录

T644887 T1

题意:

给出 n 个数,这个数肯定是0~100之间的整数,如果这个数在90以上,那么就输出4.0。如果在60~89之间,那么比每比90少一个数,它就会在4.0的基础上减0.1。若不到60分,那么就请先将他的分数调整到根号 x 乘10向下取整再计算。x 为他的分数。若调整之后一不到60,那么就输出0.0。

错误代码:


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin>>n;
	cout<<fixed<<setprecision(1);
	if(n>=90)
	{
		cout<<"4.0";
	} 
	else if(n>=60)
	{
		double s=90-n;
		double ss=0.1*s;
		cout<<4.0-ss;
	}
	else 
	{
		double a=sqrt(n)*10;
		if(a<60)
		{
			cout<<"0.0";
		}
		else 
		{
			double s=90-a;
			double ss=0.1*s;
			cout<<4.0-ss;
		}
	}
	return 0;
}

错误原因:

double 存开根号之后的结果的话,就无法做到向下取整。
  else 
		{
			double s=90-a;
			double ss=0.1*s;
			cout<<4.0-ss;
		}
//31~36

正确代码:


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin>>n;
	cout<<fixed<<setprecision(1);
	if(n>=90)
	{
		cout<<"4.0";
	} 
	else if(n>=60)
	{
		int s=90-n;
		cout<<4.0-0.1*s;
	}
	else 
	{
		int a=sqrt(n)*10;
		if(a<60)
		{
			cout<<"0.0";
		}
		else 
		{
			int s=90-a;
			cout<<4.0-0.1*s;
		}
	}
	return 0;
}

正确思路:

直接根据题目意思进行模拟。

T644888 T2

题意:

有 n 行 m 列共 n×m 个坑,每个坑可能有一个萝卜,也可能没有。
现在 Farmer John 需要至少拔 k 个萝卜,他只能挑一个矩形(长方形或正方形)区域的坑进行拔萝卜。
请你求出,为了至少拔 k 个萝卜,他需要挑的矩形面积(坑的数量)最小是多少。

正确代码:


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int n,m,k;
int a[25][25];
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
		}
	}
	int minn=INT_MAX;
	for(int i1=1;i1<=n;i1++)
	{
		for(int j1=1;j1<=n;j1++)
		{
			for(int i2=i1;i2<=n;i2++)
			{
				for(int j2=j1;j2<=n;j2++)
				{
					int cnt=0;
					int cnt2=0;
					for(int i=i1;i<=i2;i++)
					{
						for(int j=j1;j<=j2;j++)
						{
							cnt+=a[i][j];
							cnt2++;
						}
					}
					if(cnt>=k)
					{
						minn=min(minn,cnt2);
					}
				}
			}
		}
	}
	cout<<minn;
	return 0;
}

正确思路:

n,m非常小,只有20,所以可以用6层循环遍历出所有情况。

T644890 T4

题意:

传入三个参数,P1,P2,P3。
p 1=1 时,对于字母子串,填充小写字母;p1=2 时,对于字母子串,填充大写字母。这两种情况下数字子串的填充方式相同。p1=3 时,不论是字母子串还是数字字串,都用与要填充的字母个数相同的星号 * 来填充。
p2=k 表示同一个字符要连续填充 k 个。例如,当p2=3 时,子串d-h 应扩展为 deeefffgggh。减号两边的字符不变。
p3:是否改为逆序:p 3=1 表示维持原来顺序,p3=2 表示采用逆序输出
遇到下面的情况需要做字符串的展开:在输入的字符串中,出现了减号 - ,减号两侧同为小写字母或同为数字,且按照 ASCII 码的顺序,减号右边的字符严格大于左边的字符。
如果减号右边的字符恰好是左边字符的后继,只删除中间的减号

错误代码:


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int s1,s2,s3;
void zx(char a1,char a2)
{
	for(int j=a1+1;j<a2;j++)
	{
		for(int q1=1;q1<=s2;q1++)
		{
			cout<<char(j);
		}
	}
	return ;
}
void fx(char a1,char a2)
{
	for(int j=a2-1;j>a1;j--)
	{
		for(int q1=1;q1<=s2;q1++)
		{
			cout<<char(j);
		}
	}
	return ;
}
void xx(char a1,char a2)
{
	for(int j=a2-1;j>a1;j--)
	{
		for(int q1=1;q1<=s2;q1++)
		{
			cout<<"*";
		}
	}
	return ;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>s1>>s2>>s3;
	string s;
	cin>>s;
	for(int i=0;i<s.size();i++)
	{
		if(s[i+1]=='-'&&s[i]>='a'&&s[i]<='z'&&s[i+2]>='a'&&s[i+2]<='z'&&s[i]<s[i+2]||s[i]>='0'&&s[i]<='9'&&s[i+2]>='0'&&s[i+2]<='9'&&s[i+1]=='-'&&s[i]<s[i+2])
		{
			if(s[i]>='a'&&s[i]<='z'&&s[i+2]>='a'&&s[i+2]<='z')
			{
				if(s1==1)
				{
					cout<<s[i];
					if(s3==1)
					{
						zx(s[i],s[i+2]);
					}
					else
					{
						fx(s[i],s[i+2]);
					}
					cout<<s[i+2];
				}
				else if(s1==2)
				{
					cout<<s[i];
					if(s3==1)
					{
						zx(s[i]-32,s[i+2]-32);
					}
					else
					{
						fx(s[i]-32,s[i+2]-32);
					}
					cout<<s[i+2];
				}
				else
				{
					cout<<s[i];
					if(s3==1)
					{
						xx(s[i],s[i+2]);
					}
					else
					{
						xx(s[i],s[i+2]);
					}
					cout<<s[i+2];
				}
			}
			else if(s[i]>='0'&&s[i]<='9'&&s[i+2]>='0'&&s[i+2]<='9')
			{
				if(s1!=3)
				{
					cout<<s[i];
					if(s3==1)
					{
						zx(s[i],s[i+2]);
					}
					else
					{
						fx(s[i],s[i+2]);
					}
					cout<<s[i+2];
				}
				else 
				{
					cout<<s[i];
					if(s3==1)
					{
						xx(s[i],s[i+2]);
					}
					else
					{
						xx(s[i],s[i+2]);
					}
					cout<<s[i+2];
				}
			}
			i++;
			i++;
		}
		else if(s[i+1]=='-'&&s[i]>='a'&&s[i]<='z'&&s[i+2]>='0'&&s[i+2]<='9'||s[i+2]>='a'&&s[i+2]<='z'&&s[i]>='0'&&s[i]<='9')
		{
			cout<<s[i]<<s[i+1]<<s[i+2];
			i++;
			i++;
		}
		else if(s[i]=='-')
		{
			cout<<s[i]<<s[i+1];
			i++;
		}
		else
		{
			if(i==0)
			{
				cout<<s[i];
			}
			else if(s[i-1]!='-'&&s[i]!='-')
			{
				cout<<s[i];
			}
		}
	}
	return 0;
}
代码过于臃肿,判断过多.

正确代码:


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int p1,p2,p3;
void f(int s1,int s2)
{
	if(s1>='0'&&s1<='9'&&s2>='0'&&s2<='9'||s1>='a'&&s1<='z'&&s2>='a'&&s2<='z')
	{
		if(s1+1==s2)
		{
			return;
		}
		if(s1>=s2)
		{
			cout<<'-';
			return ;
		}
		if(p1==2)
		{
			if(s1>='a'&&s1<='z'&&s2>='a'&&s2<='z')
			{
				s1-=32;s2-=32;
			}
		}
		string m="";
		int z=1;
		if(p1==3)
		{
			z=0;
		}
		for(int i=s1+1;i<=s2-1;i++)
		{
			for(int j=1;j<=p2;j++)
			{
				if(z==0)
				{
					m+='*';
				}
				else
				{
					m+=char(i);
				}
			}
		}
		if(p3==2)
		{
		    for(int i=m.size()-1;i>=0;i--)
		    {
		    	cout<<m[i];
			}
		}
		else
		{
			cout<<m;
		}
	}
	else
	{
		cout<<'-';
	}
} 
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>p1>>p2>>p3;
	string s;
	cin>>s;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]=='-')
		{
			f(s[i-1],s[i+1]);
		}
		else
		{
			cout<<s[i];
		}
	}
	return 0;
}

正确思路:

用一个函数来进行输出。同时将多余的判断过滤掉。因为根据题目意思,我们可以在判断数字的时候将 P1的前面两种情况直接过滤掉。同时根据这种方案开始过滤掉一些其他的多余的,最后再统一进行输出。

T644892 T5

题意:

给出起点和终点的坐标,及接下来 T 个时刻的风向(东南西北),每行一个字符,表示风向,即东(E)南(S)西(W)北(N)的英文单词的首字母。每个时刻可以选择顺风偏移 1 个单位或者停在原地。求到达终点的最少移动步数。
坐标采用平面直角坐标系,x 轴正向为东,y 轴正向为北。

正确代码:


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int x1,x2,y1,y2;
	cin>>x1>>y1>>x2>>y2;
	int n,cnt=0;
	cin>>n;
	while(n--)
	{
		char s;
		cin>>s;
		if(s=='E')
		{
			if(x1<x2)
			{
				cnt++;
				x1++;
			}
		}
		if(s=='W')
		{
			if(x1>x2)
			{
				cnt++;
				x1--;
			}
		}
		if(s=='S')
		{
			if(y1>y2)
			{
				cnt++;
				y1--;
			}
		}
		if(s=='N')
		{
			if(y1<y2)
			{
				cnt++;
				y1++;
			}
		}
	}
	if(y1==y2&&x1==x2)
	{
		cout<<cnt;
	}
	else
	{
		cout<<"-1";
	}
	return 0;
}

正确思路:

直接根据题目意思逐个判断进行模拟。

T644895 T7

题意:

第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数.一个整数,即最短跳跃距离的最大值。

正确代码:


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
ll a[50005],m,n,k;
int f(ll x)
{
	ll wz=0;
	ll cnt=0;
	for(int i=1;i<=n+1;i++)
	{
		if(a[i]-wz<x)
		{
			cnt++;
		}
		else
		{
			wz=a[i];
		}
	}
	if(cnt<=m)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>k>>n>>m;
	for(int i=1;i<=n;i++)
	{
	    cin>>a[i];
	}
	a[n+1]=k;
	ll l=0,r=1000000005,mid;
	while(l+1<r)
	{
		mid=(l+r)/2;
		if(f(mid)==1)
		{
			l=mid;
		}
		else
		{
			r=mid;
		}
	}
	cout<<l;
	return 0;
}

正确思路:

数据很大,要用二分查找法的方式查找。
	ll wz=0;
	ll cnt=0;
	for(int i=1;i<=n+1;i++)
	{
		if(a[i]-wz<x)
		{
			cnt++;
		}
		else
		{
			wz=a[i];
		}
	}
代码用于判断当前中间值,也就是我们所选的这个最小值它是否可以满足移动 M块石头的情况

总结:

做题目的时候需要仔细读题目,并且仔细的选择你学过的算法进行解题。同时要注意题目中的关键词,以此来判断我们可以用什么数据类型。比如向下取整,我们就可以用 int 类型的自动取整方式,直接向下取整。同时在模拟题目中,要总结题目中模拟相同的部分,不要一味的去进行过多的判断。