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 类型的自动取整方式,直接向下取整。同时在模拟题目中,要总结题目中模拟相同的部分,不要一味的去进行过多的判断。