填空题:数字拆分
思路:一开始递推推错了,改用dfs
代码:
#include<iostream>
using namespace std;
int ans;
void dfs(int x, int sum){//表示从x开始搜,sum为当前数字和
if(sum == 10){
ans++;
return ;
}
//记住i从x开始搜的这一剪枝,不仅仅可以提升效率
//更重要的是可以保证搜索出来的结果不会重复,是有序的
for(int i = x; i <= 10 - sum; i++){
dfs(i, sum + i);
}
}
int main(){
dfs(1, 0);
cout << ans << endl;
return 0;
}
程序设计:好友
在蒜国,有 n 户渔民住在海岸线上,整齐的排列成一条直线。每个渔民的房子我们用一个坐标 pi 来表示,每个渔民的活动半径为 d。也就是说两个距离小于等于 d 的房子,这两户渔民相互认识,是好友。
那么在蒜国,有多少对渔民相互认识?
输入格式
第一行输入两个整数 n,d。
第二行输入 n 个整数 pi,表示每个渔民房子的坐标(存在坐标相同的 pi)。
输出格式
输出一个整数,表示有多少对渔民相互认识。
数据范围
对于 50% 的数据范围:1≤n≤10^3。
对于 100% 的数据范围:1≤n≤10^5,1≤d≤10^4,1≤pi≤10^8。
样例输入复制
5 10 10 12 16 37 40
样例输出复制
4
思路:
一开始用暴力,双重for循环枚举所有的答案
看了题解才知道我是个弟弟,这么好用的upper_bound二分我竟然没想到用
awsl
代码:
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n, d;
int p[101000]; //这题还有两个坑点,一个是数组要开到1e6
ll sum; //第二个就是sum不用ll会爆
int main(){
ios::sync_with_stdio(false);
cin >> n >> d;
for(int i = 0; i < n; i++){
cin >> p[i];
}
sort(p, p + n); //前提是有序
for(int i = 0; i < n; i++){ //多减1是因为找到的这个元素已经不满足小于d距离的条件了,所以它不属于朋友
sum += upper_bound(p, p + n, p[i] + d) - p - i - 1;
}
cout << sum << endl;
return 0;
}