分数 15
作者 ljw
单位 广东外语外贸大学
小明酷爱数学,因为数学实在是太有趣了,因此他天天做数学题,但是聪明的小明也是会遇到困难的。有一天他的山老师题出了一个问题:一个集合存在n个数,请问集合中有多少个数,恰好等于集合中另外两个数之和?小明想不到方法,只能一个一个计算,但是着实在太麻烦了,他知道你已经做出来这道题,所以向你发出了求救请求,用代码帮助小明解决此问题。
输入格式:
输入一个数字n,(0=<n<=100)表示集合中数字的个数,接下来的一行,包含n个集合中的数字。其中集合中的数字大小不超过10000.
输出格式:
输出该题目的答案。
输入样例:
4
1 2 3 4
输出样例:
在这里给出相应的输出。例如:
2
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
我的思路:
利用选择排序(只是让我联想到了选择排序时第i个和第i+1个到第n个元素比较,找出最大或最小值,但也没啥关联)的双重for循环求集合中两个元素的和,再遍历数组,有相同元素就让count加一,特别注意的是,count可能会加多了。因为如果集合是1 2 3 4 5 ,第一个元素和第四个元素及第二个元素和第三个元素相加都等于第五个元素,本来应该count只加一就好了,但我们的count却加了二。所以我弄了个数组来标记这个元素之前有没有满足条件。
代码实现:
#include<stdio.h>
int main(){
int n,a[110],b[110],c[110]={0},count=0;//b数组用来看两元素之和有没有和集合中的元素相同的,c数组用来标记;
int i,j,k;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
for(i=0;i<n-1;i++){
for(j=i+1;j<n;j++){//这个双重循环就是选择排序的双重循环
for(k=0;k<n;k++){
if(a[i]+a[j]==b[k]&&i!=k&&j!=k&&c[k]==0){
c[k]=1;//标记已经满足条件的元素下标
count++;
}
}
}
}
printf("%d",count);
}
温馨提示:不要直接复制代码哦,复制完会有一些奇奇怪怪的符号,要把它们删掉才行。但PTA上显示不出来,dev c++就可以。
我的写题过程:
我刚开始写的时候把a数组从小到大排序了,然后没考虑到count会重复加的问题。其实就算从小到大排序了也会有重复加的问题,因为就像前面举的例子,这个我当初没考虑到。但如果从小到大排序,那第三重循环就可以从k=j+1开始了,因为j+1之前的元素一定小于等于a[i]+a[j]。 还有,集合中的元素是没有重复的,这就是集合的互异性。我也测试了一些错误例子,就是集合中有相同的元素,忘记了集合的互异性。
无关话题:
写写博客还是有点用的吧,至少集合的互异性是我写着写着才发现的,这个是我们老师前几3天布置的限时作业,当时没整出来。就是卡在了那个count重复加的点,还有集合的互异性没想到,测试了一些错误样例。