P2141 珠心算测验
1.桶排序思路(借鉴)
首先要理解题目的意思,就是两个数的和,只能出现一次。
如5 5=1+4 5=2+3 也只算一次
1.这个题目只要考虑两个 出现的数 两个数的和
2.首先可以用一个数组存放出现的数(用下标)
3.然后再用一个数组存放两个数的和,(并计算出现的次数)
4.然后可以统计满足的个数(范围最大就为10000,因为输入的最大数就为n,而两个数的和也在数组中)
2.源码
#include<stdio.h>
int t[200005],g[200005];
/*t是桶,t[i]表示值为i的数在集合中两两相加出现了几次,
g[i]表示值为i的数是否在集合中,1为在,0为不在
*/
int n,a[105],ans;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);//读入
g[a[i]]=1;//在集合中赋值为1
}
for (int i=1;i<n;i++){//枚举
for (int j=i+1;j<=n;j++){
t[a[i]+a[j]]++;//被加出来了
}
}
for (int i=1;i<=10000;i++){
if (t[i]>0&&g[i]) ans++;//判断是否满足,满足ans++
}
printf("%d",ans);
return 0;
}
3.暴力思路
输入术后,直接使用三重for循环。
但也要注意将数组中使用过的两个数之和标记(去重),
(由于数没有排序,则要注意三个数不能相同)。
4.源码
#include<stdio.h>
int main() {
int a[101],s,n,vk[101]={0};
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)//
for(int k=1;k<=n;k++)//
if(a[i]+a[j]==a[k]&&vk[k]==0&&k!=i&&k!=j){//v判重,0代表未标记
s++;
vk[k]=1;
}
printf("%d",s);
return 0;
}
错误解法(考虑不充分)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
int a[20005]={0},t[20005]={0};
cin>>n;
int ans=0,x;
for(int i=1;i<=n;i++){
cin>>x;
a[x]=x;
}
for(int i=1;i<=n-1;i++){
for(int j=i+1;j<=n;j++){
if(a[a[i]+a[j]])
//此时a[i]可能没在数组例,所以这样是错误的
t[a[i]+a[j]]++;
}
}
for(int i=1;i<=20005;i++){
if(a[i]&&t[i]>0)
ans++;
}
cout<<ans<<endl;
return 0;
}