第九周期末(中)考试解题报告
最近手癌经常打错字大家见谅。
本周期末考试不知道大家感觉如何呢?不过我猜想这种比赛的紧迫感还是很陌生的吧。状态不好的话不要紧,多写点题以及平时注意限制自己做题的时间,不要太拖沓就能改善这种状态了。
1000. Triangle
解:初中数学题,两边之差小于第三边,两边之和大于第三边,以此为界限即可。注意输出格式。
代码:
1001. Sort
解:这题做法非常多,常规做法是使用排序把数据从小到大输出,或者你可以开四个变量记录50,100,500,1000有多少个,用if输出即可。这里我还是直接用排序做了。
(有兴趣学开挂的同学学习下stl库里的sort函数)
代码:
//想引用我这个话的时候百度一下= =,在同学的指正下发现我只是顾着酷炫值乱用成语了。
本周期末考试不知道大家感觉如何呢?不过我猜想这种比赛的紧迫感还是很陌生的吧。状态不好的话不要紧,多写点题以及平时注意限制自己做题的时间,不要太拖沓就能改善这种状态了。
1000. Triangle
解:初中数学题,两边之差小于第三边,两边之和大于第三边,以此为界限即可。注意输出格式。
代码:
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
cout << '(' << abs(a-b) << ", "<< abs(a+b) << ')' << endl;
return 0;
} 1001. Sort
解:这题做法非常多,常规做法是使用排序把数据从小到大输出,或者你可以开四个变量记录50,100,500,1000有多少个,用if输出即可。这里我还是直接用排序做了。
(有兴趣学开挂的同学学习下stl库里的sort函数)
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 1111
int n, a[MAXN]={0};
int main(){
cin>>n;
for (int i=1; i<=n; i++){
int tmp;
scanf("%d", &tmp);
a[tmp]++;
}
for (int i=1; i<=1000; i++)
if (a[i]) {
while (a[i]--){
printf("%d", i);
if (a[i]) printf(" ");
else printf("\n");
}
}
return 0;
}
1002. Square
解:我的做法是把四条边化作从原点为起点的向量,然后先判断向量是否长度都是一样,先确定这个四边形是一个菱形,然后一个菱形是正方形的充要条件是其中有一个直角即可,而需找直角的公式题目当中最下方也已经给出来了。
代码:
1003. Array
解:前缀和的变形,分别求出奇数项的前缀和和偶数项的前缀和即可~。这样就能快速查询某个区间的权值和了。详细可以参考代码实现。代码中b数组记录奇数前缀和,c数组记录偶数前缀和,而a就是记录读入初始数组。
代码:
PS:注释起来的语句是用来调试用的,我发现了一个细节问题就是<cmath>和<algorithm>库里貌似都有abs函数,但是他们的用法和实现有点不一样的。建议使用algorithm里的abs函数。在本地做得时候这题因为这个问题挂了。
1004. Polynomial
解:大魔王题目。
很多人用枚举来做,枚举每个多项式内选取ax项还是b项然后乘起来。其实我感觉这样做就很笨拙了。其实就模拟人手工展开多项式就好了
比如 (x+2)(x+3) 不要用什么十字相乘,你用笔纸算算看步骤?
其实可以提出出系数 (1, 2)*(1, 3)
可以看作 1 2
* 1 3
————————
3 6
1 2
————————
1 5 6
答案是 x^2+5x+6,是不是呢?
wzm大神总结得好(你们看好了是wzm不是wmz,不是我!)其实这个问题的本质可以看做不进位的乘法就好了。
那么我的程序就直接模拟了这个乘法过程,输出的时候注意符号,系数这些细节就ok啦!
代码:
写在最后:
考试有点像竞赛,他不可能让你慢慢悠悠地去做题,所以,有一些你平常可以发挥的能力就发挥不出来了。
那么怎么解决呢?就像我最开始讲的,限制做题时间,训练紧张感。
但是这不是根本解决问题的办法,至少从我这种笨拙型的竞赛选手看来,是不存在一种能够排除做题在外而提高自己的思考和代码实现能力的办法的。
所以题目的练习数量一定要保证。如果想及格,那么你必须能够在程序设计课的两节课以内就把课程作业做完。
而如果想追求优秀,那还远远不够。
我曾经在一个大牛的博客内看到这样一句签名,很喜欢:
积羽沉舟,群轻折轴。
1002. Square
解:我的做法是把四条边化作从原点为起点的向量,然后先判断向量是否长度都是一样,先确定这个四边形是一个菱形,然后一个菱形是正方形的充要条件是其中有一个直角即可,而需找直角的公式题目当中最下方也已经给出来了。
代码:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define SQR(x) ((x)*(x))
#define EPS (1e-8)
struct point{int x, y;};
bool flag;
point a[10], b[10];
bool check(){
double dist=sqrt(SQR(b[1].x) + SQR(b[1].y));
for (int i=2; i<=4; i++){
double tmp=sqrt(SQR(b[i].x) + SQR(b[i].y));
if (abs(tmp-dist)>EPS) return false;
}
if (abs(b[1].x*b[2].x+b[1].y*b[2].y)>EPS) return false;
return true;
}
int main(){
for (int i=1; i<=4; i++){
scanf("%d%d", &a[i].x, &a[i].y);
}
a[5]=a[1];
for (int i=1; i<=4; i++){
b[i].x=a[i+1].x-a[i].x;
b[i].y=a[i+1].y-a[i].y;
}
flag=check();
if (flag) cout << "Yes\n";
else cout << "No\n";
return 0;
} 1003. Array
解:前缀和的变形,分别求出奇数项的前缀和和偶数项的前缀和即可~。这样就能快速查询某个区间的权值和了。详细可以参考代码实现。代码中b数组记录奇数前缀和,c数组记录偶数前缀和,而a就是记录读入初始数组。
代码:
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
#define MAXN 1111
int a[MAXN]={0}, b[MAXN]={0}, c[MAXN]={0};
int n,m;
int main(){
cin>>n;
for (int i=1; i<=n; i++){
scanf("%d", &a[i]);
}
for (int i=1; i<=n; i++){
b[i]+=b[i-1]; c[i]+=c[i-1];
if (i&1==1) b[i]+=a[i];
else c[i]+=a[i];
}
//for (int i=1; i<=n; i++) cout << b[i] << endl;
cin>>m;
int x,y;
while (m--){
scanf("%d%d", &x, &y);
//cout << b[y]-b[x-1] << endl;
//cout << c[y]-c[x-1] << endl;
int tmp=abs((b[y]-b[x-1])-(c[y]-c[x-1]));
printf("%d\n", tmp);
}
return 0;
} PS:注释起来的语句是用来调试用的,我发现了一个细节问题就是<cmath>和<algorithm>库里貌似都有abs函数,但是他们的用法和实现有点不一样的。建议使用algorithm里的abs函数。在本地做得时候这题因为这个问题挂了。
1004. Polynomial
解:大魔王题目。
很多人用枚举来做,枚举每个多项式内选取ax项还是b项然后乘起来。其实我感觉这样做就很笨拙了。其实就模拟人手工展开多项式就好了
比如 (x+2)(x+3) 不要用什么十字相乘,你用笔纸算算看步骤?
其实可以提出出系数 (1, 2)*(1, 3)
可以看作 1 2
* 1 3
————————
3 6
1 2
————————
1 5 6
答案是 x^2+5x+6,是不是呢?
wzm大神总结得好(你们看好了是wzm不是wmz,不是我!)其实这个问题的本质可以看做不进位的乘法就好了。
那么我的程序就直接模拟了这个乘法过程,输出的时候注意符号,系数这些细节就ok啦!
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
long long a[10][10]={0};
int n;
int main(){
cin>>n;
for (int i=1; i<=n; i++){
for (int j=1; j<=2; j++) scanf("%lld", &a[i][j]);
}
a[1][0]=2;
for (int k=2; k<=n; k++){
for (int i=1; i<=a[1][0]; i++){
for (int j=1; j<=2; j++){
a[0][i+j-1]+=a[1][i]*a[k][j];
}
}
a[1][0]++;
for (int i=1; i<=a[1][0]; i++){
a[1][i]=a[0][i];
}
for (int i=1; i<=9; i++) a[0][i]=0;
}
//cout << a[1][1] << endl;
long long tmp;
for (int i=1; i<=a[1][0]; i++){
tmp=abs(a[1][i]);
if (a[1][i]==0) continue;
if (a[1][i]<0) cout <<'-';
else {
if (i>1) cout <<'+';
}
if (i<a[1][0]){
if (tmp!=1) cout << tmp;
cout << 'x';
if (n-i+1>1) cout << '^'<<n-i+1;
}
else cout << tmp;
}
cout << endl;
return 0;
} 写在最后:
考试有点像竞赛,他不可能让你慢慢悠悠地去做题,所以,有一些你平常可以发挥的能力就发挥不出来了。
那么怎么解决呢?就像我最开始讲的,限制做题时间,训练紧张感。
但是这不是根本解决问题的办法,至少从我这种笨拙型的竞赛选手看来,是不存在一种能够排除做题在外而提高自己的思考和代码实现能力的办法的。
所以题目的练习数量一定要保证。如果想及格,那么你必须能够在程序设计课的两节课以内就把课程作业做完。
而如果想追求优秀,那还远远不够。
我曾经在一个大牛的博客内看到这样一句签名,很喜欢:
积羽沉舟,群轻折轴。
//想引用我这个话的时候百度一下= =,在同学的指正下发现我只是顾着酷炫值乱用成语了。