[codeforces 1353D] Constructing the Array 分治算法

Codeforces Round #642 (Div. 3)  参与排名人数11823

[codeforces 1353D]   Constructing the Array   分治算法

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址http://codeforces.com/contest/1353/problem/D

ProblemLangVerdictTimeMemory
D - Constructing the Array GNU C++17Accepted77 ms7500 KB

本场比赛最大收获,在比赛中悟出了分治算法(这个是弱项),并且AC掉该题。那种感觉真奇妙。

思路:

通过分治算法,找出所有可放数据的区间,将区间按区间长度,自大到小排序,若区间长度相同,按左边界自小到大排序。

之后,将放置的数据,按顺序放入安置区间对应的安置位置。

样例分析如下

n=6
(1,6)中的3位置可放置数据
(1,6)剩下的可放置数据的区间是(1,2),(4,6)

(1,2)中的1位置可放置数据
(4,6)中的5位置可放置数据

(1,2)剩下的可放置数据的区间是(2,2)
(2,2)中的2位置可放置数据

(4,6)剩下的可放置数据的区间是(4,4),(6,6)
(4,4)中的2位置可放置数据
(6,6)中的6位置可放置数据

可放置数据的区间如下
(1,6),a[3]=1
(4,6),a[5]=2
(1,2),a[1]=3
(2,2),a[2]=4
(4,4),a[4]=5
(6,6),a[6]=6

AC代码如下

#include <cstdio>
#include <algorithm>
using namespace std;
int a[200010],cnt,tot;
struct node{
	int left,right,mid,delta;//left记录区间左边界,right记录区间右边界,mid记录区间放置数据位置,delta记录区间长度
}b[200010];
int cmp(node a,node b){
	return a.delta==b.delta?a.left<b.left:a.delta>b.delta;//将区间按区间长度,自大到小排序,若区间长度相同,按左边界自小到大排序。
}
void dfs(int left,int right){
	int mid;
	if(left>right)return;//结束条件
	tot++,b[tot].left=left,b[tot].right=right,b[tot].mid=(left+right)/2,b[tot].delta=right-left+1,mid=(left+right)/2;//记录安置区间的数据
	dfs(left,mid-1),dfs(mid+1,right);//区间分裂,请注意,mid位置已被占用,故mid-1,mid+1
}
int main(){
	int t,n,i;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		for(i=1;i<=n;i++)a[i]=0;//初始化
		for(i=1;i<=n;i++)b[i].left=b[i].right=b[i].delta=0;//初始化
		cnt=0,tot=0;//初始化,tot记录安置区间的数量
		dfs(1,n);//找出安置数据的区间
		sort(b+1,b+1+tot,cmp);//将区间按区间长度,自大到小排序,若区间长度相同,按左边界自小到大排序。
		for(i=1;i<=tot;i++)a[b[i].mid]=++cnt;//cnt是指需要放置的数据
		for(i=1;i<=n;i++)printf("%d ",a[i]);
		printf("\n");
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值