基础分治总结

基础分治总结

前记:边敲代码边写博客,本专题完成速度取决于敲代码过题速度(好像没啥写的,就写四个意思一下吧)。分治,其目的在于将一个大问题分解成很多小问题,依次求得其解,而得到最终答案。

文章目录

    • 基础分治总结
      • 【分治】金块问题
      • 【分治】桐桐查单词
      • 【分治】化装晚会
      • 【分治】珍珠项链

【分治】金块问题

题目描述:
一个老板有一袋金块,里面有n块金子。每个月,老板会从袋子中拿出两个金块奖励两名期雇员。按规矩,最优秀的雇员将得到袋中最重的金块,排名第二的雇员将得到袋中最轻的金块。周期性地往袋中加入新的金块,那么每个月他都要找出最重和最轻的金块。假设有一台比较质量的仪器,我们希望用尽量少的比较次数找出最重和最轻的金块。
输入:
第1行只有一个整数n(2≤n≤100000)。
第2行n个长整型范围内的整数,每个整数之间用一个空格隔开,表示每块金子的质量。
输出:
输出两个用空格分开的整数,表示最重和最轻的金块的质量。
样例输入:
8
10 8 2 4 5 3 9 1
样例输出:
10 1
题目原意应该是要用二分。。但是数据这么水,暴力完全可以过。

#include 
#include 
#define N 1000000
int main()
{long int n,a[N];long int i,max=0,min=100000;scanf("%ld",&n);for(i=1;i<=n;i++){scanf("%ld",&a[i]);if(a[i]>max) max=a[i];if(a[i]<min) min=a[i];}printf("%ld %ld\n",max,min);return 0;
}

【分治】桐桐查单词

题目描述:
今天桐桐接到一个任务,就是要把一篇英语文章翻译成中文。对桐桐来说这任务实在太艰巨的桐桐只好拿着英文字典,一句句慢慢翻译起来。希望桐桐能在规定的时间内完成吧。
输入:
第1行一个整数N,表示字典中一共有多少单词(N≤20000)。

接下来每两行表示一个单词,其中:

第1行是一个长度≤100的字符串,表示这个单词,全部字母小写,单词不会重复。

第2行是一个整数,表示这个单词在字典中的页码。

接下来一行是一个整数W,表示要查的单词数(M≤10000)。

接下来M行,每行一个字符串,表示要查的单词,保证在字典中存在。
输出 :
M行,每行一个整数,表示第i个单词在字典中的页数。
样例输入:
2
scan
10
word
15
2
scan
word
样例输出:
10
15
map映射,直接搞定。

#include
using namespace std;
typedef long long ll;
map<string,int>mapp;
int main()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){string str;cin>>str;int num;scanf("%d",&num);mapp[str]=num;}int m;scanf("%d",&m);for(int i=1;i<=m;i++){string str;cin>>str;printf("%d\n",mapp[str]);}return 0;
}

【分治】化装晚会

题目描述:
万圣节又到了!FJ打算带他的奶牛去参加化装晚会,但是,FJ只做了一套能容下两头总长不超过S (1≤S≤1000000)的奶牛恐怖服装。FJ养了N(2≤N≤20000)头按1–N顺序编号的奶牛,编号为i的奶牛的长度为L_i(1≤L_i≤1000000)。如果两头奶牛的总长度不超过S,那么她们就能穿下这套服装。
FJ想知道,如果他想选择两头不同的奶牛来穿这套衣服,一共有多少种满足条件的方案。
输入:
第1行是2个整数:N和S;
第2~N+l行每行一个整数:L_i。
输出:
1个整数,表示FJ可选择的所有方案数。注意奶牛顺序不同的两种方案是被视为相同的。
样例输入:
4 6
3
5
2
1
样例输出:
4
先从小到大排序,然后从第一个开始,只搜其后的,有几个能穿上就加几,但肯定不能一个一个搜啊,所以,二分就行了。

#include
using namespace std;
typedef long long ll;
int a[20005];
int erfen(int start,int endd,int l)
{int mid=(start+endd)/2;if((a[mid]<=l&&a[mid+1]>l)||(mid==endd&&a[mid]<=l))return mid;else if(a[mid]<=l)return erfen(mid+1,endd,l);else if(a[mid]>l){if(start!=mid)return erfen(start,mid,l);elsereturn start-1;//二分时要注意这种特殊情况,搜索不到要返回start-1}
}
int main()
{int n,l;int ans=0;scanf("%d%d",&n,&l);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}sort(a+1,a+1+n);for(int i=1;i<n;i++){ans+=(erfen(i+1,n,l-a[i])-i);}printf("%d\n",ans);return 0;
}

【分治】珍珠项链

题目描述:
我有很多(n条)珍珠项链,每天我都要从中挑一条戴上……挑哪条很有讲究,不能太难看也不能太好看。所以我希望你能帮帮我,解决这个问题――每天帮我算算,那天我能戴的项链有多少条。
输入:
第1行为正整数n,表示项链的总条数(n≤100000);
第2行有n个整数(代表每条项链晶的好看程度Xi,0≤Xi≤maxlongint);
第3行为正整数m,表示总天数(也就是总询问次数,其中m≤100000);
以下m行,每行两个整数Ai,Bi(1≤Ai,Bi≤maxlongint),询问好看程度在Ai到Bi之间的项链条数(含等于Ai或Bi的,Ai与Bi大小关系不确定)。
输出:
输出m行,对于每次询问输出一行,从Ai到Bi(含Ai,Bi)好看程度在Ai到Bi之间的项链条数。
样例输入:
7
8 2 3 5 6 7 7
6
1 5
8 6
1 10
5 5
4 4
7 8
样例输出:
3
4
7
1
0
3
把上面那个题稍微改一下就行了,上面那个是<=,这道题多判断一个<,即加一种二分。

#include
using namespace std;
typedef long long ll;
ll a[100005];
int erfen(int start,int endd,int l)
{int mid=(start+endd)/2;if((a[mid]<=l&&a[mid+1]>l)||(mid==endd&&a[mid]<=l))return mid;else if(a[mid]<=l)return erfen(mid+1,endd,l);else if(a[mid]>l){if(start!=mid)return erfen(start,mid,l);elsereturn start-1;}
}
int erfen1(int start,int endd,int l)
{int mid=(start+endd)/2;if((a[mid]<l&&a[mid+1]>=l)||(mid==endd&&a[mid]<l))return mid;else if(a[mid]<l)return erfen1(mid+1,endd,l);else if(a[mid]>=l){if(start!=mid)return erfen1(start,mid,l);elsereturn start-1;}
}
int main()
{int n;int ans=0;scanf("%d",&n);for(int i=1; i<=n; i++){scanf("%lld",&a[i]);}sort(a+1,a+1+n);int m;scanf("%d",&m);while(m--){int x,y;scanf("%d%d",&x,&y);if(x>y){x^=y;y^=x;x^=y;}ans=erfen(1,n,y)-erfen1(1,n,x);printf("%d\n",ans);}return 0;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部