AcWing语法基础课错题记录

AcWing 604. 圆的面积

错误代码:

1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
int main ()
{
float PI=3.14159;
float R;
cin>>R;
cout<<"A="<< PI*R*R<<endl;
return 0;
}

测试输入

1
10.16

测试输出

1
A=324.293

标准答案

1
A=324.2925

分析原因:题目说了要保留四位小数,不用printf的话,用

1
fixed<<setprecisions(4)<<PI*R*R

试试,记得加头文件
答案仍错,把float换为double试试
测试成功,下面为正确代码

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
double PI=3.14159;
double R;
cin>>R;
cout<<"A="<<fixed<<setprecision(4)<<PI*R*R<<endl;
return 0;
}

AcWing 616.两点间的距离

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
double x1,y1,x2,y2;
cin>>x1>>y1;
cin>>x2>>y2;
cout<<fixed<<setprecision(4)<<sqrt((x1-x2)^2+(y1-y2)^2);
return 0;
}

报错a.cpp:10:22: error: invalid operands of types ‘float’ and ‘float’ to binary ‘operator^’
百度原因是因为cpp不支持平方操作
修改为

1
cout<<fixed<<setprecision(4)<<sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));

AcWing 617. 距离

题目:两辆汽车在同一地点,同时,沿同一方向前进。
一辆车的速度为 60 km/h,另一辆车的速度为 90 km/h。
显然,快车与慢车的距离会不断拉开,每过一个小时(60 分钟),两车的距离就拉开 30 公里。
现在,告诉你两车之间的距离为 L 公里,请你求出两车已经行驶了多长时间?
错误代码:

1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;
int main ()
{
int L;
cin >> L;
cout<<L/(90-60)*60<<" minutos"<<endl;
return 0;
}

错误原因:没有考虑到/是整除,L可能不是30的整数倍,此时应该如何解决问题呢?
修改:快车与慢车每小时拉开30KM,每分钟拉开0.5KM
直接把单位换算到分钟,不用小时

1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;
int main ()
{
int L;
cin >> L;
cout<<L/0.5<<" minutos"<<endl;
return 0;
}

仍然错误;此时可以看到除了0.5,变成浮点数了,数字太大的话会变成科学技术法,与标准输出不同,我们强制转换为int;

1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;
int main ()
{
int L;
cin >> L;
cout<<(int)(L/0.5)<<" minutos"<<endl;
return 0;
}

成功

AcWing 656. 钞票和硬币

错误在于,对小数进行区域操作是不可行的;
我们把小数部分扩大数量级至整数部分就能正确地使用取余操作了;
但是此处出现了问题
源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;
int main ()
{
double number;
cin>>number;
int a,b,c,d,e,f,g,h,i,j,k,l;
a=number/100;
b=(number-a*100)/50;
c=(number-a*100-b*50)/20;
d=(number-a*100-b*50-c*20)/10;
e=(number-a*100-b*50-c*20-d*10)/5;
f=(number-a*100-b*50-c*20-d*10-e*5)/2;
cout<<"NOTAS:"<<endl;
cout<<a<<" nota(s) de R$ 100.00"<<endl;
cout<<b<<" nota(s) de R$ 50.00"<<endl;
cout<<c<<" nota(s) de R$ 20.00"<<endl;
cout<<d<<" nota(s) de R$ 10.00"<<endl;
cout<<e<<" nota(s) de R$ 5.00"<<endl;
cout<<f<<" nota(s) de R$ 2.00"<<endl;
cout<<"MOEDAS:"<<endl;
g=(number-a*100-b*50-c*20-d*10-e*5-f*2)/1;
h=(number-a*100-b*50-c*20-d*10-e*5-f*2-g*1)*100/50;
i=(number-a*100-b*50-c*20-d*10-e*5-f*2-g*1-h*0.5)*100/25;
j=(number-a*100-b*50-c*20-d*10-e*5-f*2-g*1-h*0.5-i*0.25)*100/10;
k=(number-a*100-b*50-c*20-d*10-e*5-f*2-g*1-h*0.5-i*0.25-j*0.1)*100/5;
l=(number-a*100-b*50-c*20-d*10-e*5-f*2-g*1-h*0.5-i*0.25-j*0.1-k*0.05)*100/1;
cout<<g<<" moeda(s) de R$ 1.00"<<endl;
cout<<h<<" moeda(s) de R$ 0.50"<<endl;
cout<<i<<" moeda(s) de R$ 0.25"<<endl;
cout<<j<<" moeda(s) de R$ 0.10"<<endl;
cout<<k<<" moeda(s) de R$ 0.05"<<endl;
cout<<l<<" moeda(s) de R$ 0.01"<<endl;
return 0;
}

输入

1
463.01

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NOTAS:
4 nota(s) de R$ 100.00
1 nota(s) de R$ 50.00
0 nota(s) de R$ 20.00
1 nota(s) de R$ 10.00
0 nota(s) de R$ 5.00
1 nota(s) de R$ 2.00
MOEDAS:
1 moeda(s) de R$ 1.00
0 moeda(s) de R$ 0.50
0 moeda(s) de R$ 0.25
0 moeda(s) de R$ 0.10
0 moeda(s) de R$ 0.05
0 moeda(s) de R$ 0.01

标准答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NOTAS:
4 nota(s) de R$ 100.00
1 nota(s) de R$ 50.00
0 nota(s) de R$ 20.00
1 nota(s) de R$ 10.00
0 nota(s) de R$ 5.00
1 nota(s) de R$ 2.00
MOEDAS:
1 moeda(s) de R$ 1.00
0 moeda(s) de R$ 0.50
0 moeda(s) de R$ 0.25
0 moeda(s) de R$ 0.10
0 moeda(s) de R$ 0.05
1 moeda(s) de R$ 0.01

很明显最后一行的值没对上,l的值是有问题的,为啥捏??
单独输出一行

1
cout<<(number-a*100-b*50-c*20-d*10-e*5-f*2-g*1-h*0.5-i*0.25-j*0.1-k*0.05)*100/1;

结果是

1
1

我直接黑人问号????what’s your problem ??
想了想,l是int型变量,而(number-a100-b50-c20-d10-e5-f2-g1-h0.5-i0.25-j0.1-k*0.05)*100/1应该是float型;
强制转换一下输出

1
cout<<(int)((number-a*100-b*50-c*20-d*10-e*5-f*2-g*1-h*0.5-i*0.25-j*0.1-k*0.05)*100/1);

结果为

1
0

好家伙,问题果然出在这儿;
float的1转换为int居然变成0了?为啥啊??应该是储存的问题,原谅我不考计组==
那么精度丢失只影响最后一位。我们不定义l;直接输出l试试:
测试成功
这会儿倒是没问题了,但是又有新的问题出现了==
样例输入:

1
2214.9

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NOTAS:
22 nota(s) de R$ 100.00
0 nota(s) de R$ 50.00
0 nota(s) de R$ 20.00
1 nota(s) de R$ 10.00
0 nota(s) de R$ 5.00
2 nota(s) de R$ 2.00
MOEDAS:
0 moeda(s) de R$ 1.00
1 moeda(s) de R$ 0.50
1 moeda(s) de R$ 0.25
1 moeda(s) de R$ 0.10
1 moeda(s) de R$ 0.05
9.09411e-12 moeda(s) de R$ 0.01

最后一行直接芜湖起飞好吧==一看就是精度的问题
人麻了==我直接大换血,整数部分不变,小数部分开刀

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;
int main ()
{
double number;
cin>>number;
int a,b,c,d,e,f,g,h,i,j,k,l;
a=number/100;
b=(number-a*100)/50;
c=(number-a*100-b*50)/20;
d=(number-a*100-b*50-c*20)/10;
e=(number-a*100-b*50-c*20-d*10)/5;
f=(number-a*100-b*50-c*20-d*10-e*5)/2;
cout<<"NOTAS:"<<endl;
cout<<a<<" nota(s) de R$ 100.00"<<endl;
cout<<b<<" nota(s) de R$ 50.00"<<endl;
cout<<c<<" nota(s) de R$ 20.00"<<endl;
cout<<d<<" nota(s) de R$ 10.00"<<endl;
cout<<e<<" nota(s) de R$ 5.00"<<endl;
cout<<f<<" nota(s) de R$ 2.00"<<endl;
cout<<"MOEDAS:"<<endl;
g=(number-a*100-b*50-c*20-d*10-e*5-f*2)/1;
h=(number*100-a*10000-b*5000-c*2000-d*1000-e*500-f*200-g*100)/50;
i=(number*100-a*10000-b*5000-c*2000-d*1000-e*500-f*200-g*100-h*50)/25;
j=(number*100-a*10000-b*5000-c*2000-d*1000-e*500-f*200-g*100-h*50-i*25)/10;
k=(number*100-a*10000-b*5000-c*2000-d*1000-e*500-f*200-g*100-h*50-i*25-j*10)/5;
l=(number*100-a*10000-b*5000-c*2000-d*1000-e*500-f*200-g*100-h*50-i*25-j*10-k*5)/1;
cout<<g<<" moeda(s) de R$ 1.00"<<endl;
cout<<h<<" moeda(s) de R$ 0.50"<<endl;
cout<<i<<" moeda(s) de R$ 0.25"<<endl;
cout<<j<<" moeda(s) de R$ 0.10"<<endl;
cout<<k<<" moeda(s) de R$ 0.05"<<endl;
cout<<l<<" moeda(s) de R$ 0.01"<<endl;
return 0;
}

测试成功,血的教训!!不要TM玩小数,能用整数的地方坚决避免出现小数!!

AcWing 725. 完全数

源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
using namespace std;
int main()
{
int n,sum=0;
long long a;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a;
for(long long j=1;j<a;j++)
{
if(a%j==0)
sum+=j;
}
if(sum==a)
cout<<a<<" is perfect"<<endl;
else
cout<<a<<" is not perfect"<<endl;
sum=0;
}
return 0;
}

测试输入

1
2
3
4
3
6
5
28

输出

1
2
3
6 is perfect
5 is not perfect
28 is perfect

没毛病,提交后显示Time Limit Exceeded ,超时了,第一次遇到,估计是两层嵌套时间复杂度太高了
看看讲解
如果d能整除x,即d%x==0;则d/x也能整除x,即d%(d/x)==0;
例如12%2==0;12%(12/2)==12%6==0;
所以
约数从小往大取,3是12的一个约数,12/3==4是另一个约数
假设i是一个约数,则n/i>=i
即i²<=n
即i<=sqrt(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
using namespace std;
int main()
{
int a,n,sum=0;

cin>>n;
for(int i=0;i<n;i++)
{
cin>>a;
if(a==1)
cout<<"1 is not perfect"<<endl;
else
{
for(int j=1;j*j<=a;j++)
{
if(a%j==0)
sum=j+(a/j)+sum;
}
if(sum==a*2)
cout<<a<<" is perfect"<<endl;
else
cout<<a<<" is not perfect"<<endl;
sum=0;
}
}
return 0;
}

上面是正确代码,说一下需要注意的点
本题的思想是:找到一个约数就等于找到了两个约数,这样可以减小时间复杂度
比如看28是不是完全数,找约数:
1,28
2,14
4,7
找三次就能找到所有约数,再加起来,注意这里把所有的约数加上的话把本身28也加上去了,所以最后要除2

------ 本文结束 ------