IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【NOI模拟赛】伊莉斯elis(贪心,模拟) -> 正文阅读

[数据结构与算法]【NOI模拟赛】伊莉斯elis(贪心,模拟)

题面

1 ? s ????? 512 ? m b _{_{\rm1\,s~~~~~512\,mb}} 1s?????512mb??
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题解

我们会发现,任何时刻魔眼阈值最小的都是方阵的四个角之一,因此我们只需要考虑四个角上的魔眼就可以了。

判断是否有解可以贪心判断。

得到字典序最小的方案,可以每一步尝试向右+贪心判断是否有解。

那么怎么贪心判断呢?

注:以下为判断是否有解的贪心策略,并非最终输出的答案。

我们可以先把整个网格图分区:五芒星阵为魔眼区
在这里插入图片描述
由于魔眼每次减小的阈值等于曼哈顿距离,因此大方向肯定是越靠近魔眼区越好。

在 A 区域时,贪心地一路走到魔眼区左下角,中途怎么走随意,对魔眼区的影响相同。

在蓝色箭头区域,本着越靠近越好的原则,肯定是无脑往上走。

在 B 区域时,怎么走都无所谓了,对魔眼区的影响相同。

当你进入魔眼区的时候,就要麻烦点,
在这里插入图片描述
假设当前在魔眼区 ( x , y ) (x,y) (x,y) ,中途走出魔眼区肯定是不优的,所以肯定是一路走到 C C C 点,这一路对 A , C A,C A,C 的影响是相同的。出了 C C C 点之后就是随便走了,因此我们要尽量让 B , D B,D B,D 的阈值最小值最大。

左边的方案是对 B B B 最有利的、对 D D D 最有害的方案,右边的方案相反:
在这里插入图片描述
我们考虑调整法,从左边的方案调整到右边的方案,每次将一个“上右”变成“右上”,会刚好让 B B B 的阈值减少 2, D D D 的阈值增加 2 。所以,不论什么方案,对 B , D B,D B,D 的阈值贡献和是相等的,边界就是上述两种情况。我们可以 O ( 1 ) O(1) O(1) 贪心分配,使得最终 B , D B,D B,D 的阈值尽量平均。

代码实现算是一道模拟题了。

时间复杂度 O ( n ) O(n) O(n) 。既然是模拟,常数可以往大的写。

CODE

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<random>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#pragma GCC optimize(2)
using namespace std;
#define MAXN (1<<16|5)
#define LL long long
#define ULL unsigned long long
#define ENDL putchar('\n')
#define DB double
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
#define PR pair<int,int>
#define UIN unsigned int
int xchar() {
	static const int maxn = 1000000;
	static char b[maxn];
	static int pos = 0,len = 0;
	if(pos == len) pos = 0,len = fread(b,1,maxn,stdin);
	if(pos == len) return -1;
	return b[pos ++];
}
// #define getchar() xchar()
LL read() {
	LL f = 1,x = 0;int s = getchar();
	while(s < '0' || s > '9') {if(s<0)return -1;if(s=='-')f=-f;s = getchar();}
	while(s >= '0' && s <= '9') {x = (x<<1) + (x<<3) + (s^48);s = getchar();}
	return f*x;
}
void putpos(LL x) {if(!x)return ;putpos(x/10);putchar((x%10)^48);}
void putnum(LL x) {
	if(!x) {putchar('0');return ;}
	if(x<0) putchar('-'),x = -x;
	return putpos(x);
}
void AIput(LL x,int c) {putnum(x);putchar(c);}

int n,m,s,o,k;
int a,b,c;
LL A_,B_,L_,R_,t;
int Abs(int x) {return x<0 ? -x:x;}
int dis(int x,int y,int a,int b) {
	return Abs(a-x) + Abs(b-y);
}
LL sm(int l,int r) {return (l+r) *1ll* (r-l+1) / 2;}
bool check(int x,int y,LL A,LL B,LL L,LL R) {
	if(A > t || B > t || L > t || R > t) return 0;
	if(x == n+1 && y == n) return 1;
	if(x < a)
		return check(a,b,A+sm(1,dis(x,y,a,b)),B+sm(c+c+1,dis(x,y,a+c,b+c)),
		L+sm(c+1,dis(x,y,a,b+c)),R+sm(c+1,dis(x,y,a+c,b)));
	if(x >= a+c && y >= b+c)
		return check(n+1,n,A+sm(x-a+y-b,n-a+n-b),B+sm(x-a-c+y-b-c,n-a-c+n-b-c),
		L+sm(x+y-a-b-c,n+n-a-b-c),R+sm(x+y-a-b-c,n+n-a-b-c));
	if(x <= a+c && y < b)
		return check(x,b,A+sm(x-a+1,dis(x,y,a,b)),B+sm(a+c-x+c+1,dis(x,y,a+c,b+c)),
		L+sm(dis(x,b-1,a,b+c),dis(x,y,a,b+c)),R+sm(a+c-x+1,dis(x,y,a+c,b)));
	if(x > a+c && y < b)
		return check(x,b,A+sm(x-a+1,dis(x,y,a,b)),B+sm(x-a+1,dis(x,y,a,b)),
		L+sm(dis(x,b-1,a,b+c),dis(x,y,a,b+c)),R+sm(x-a-c+1,dis(x,y,a+c,b)));
	if(x > a+c && y < b+c)
		return check(x,b+c,A+sm(dis(x,y,a,b),dis(x,b+c-1,a,b)),B+sm(dis(x,b+c-1,a+c,b+c),dis(x,y,a+c,b+c)),
		L+sm(dis(x,b+c-1,a,b+c),dis(x,y,a,b+c)),R+sm(dis(x,y,a+c,b),dis(x,b+c-1,a+c,b)));
	
	A += sm(dis(x,y,a,b),c+c); B += sm(0,dis(x,y,a+c,b+c));
	LL sl = sm(x-a,dis(x,y,a,b+c)) + sm(x-a+1,c);
	L += sl; R += sm(y-b,dis(x,y,a+c,b)) + sm(y-b+1,c);
	LL ad = sm(dis(x,y,a,b+c),dis(a+c,y,a,b+c)) + sm(c,dis(a+c,y,a,b+c)-1) - sl;
	if(L+ad <= R+2) L += ad;
	else if(R+ad <= L+2) R += ad;
	else {
		if(L > R) swap(L,R);
		LL nb = R-L - ((R-L)&1); L += nb; ad -= nb;
		if(ad & 3) ad -= 2,L += 2;
		L += ad>>1; R += ad>>1;
	}
	return check(a+c+1,b+c,A,B,L,R);
}
int main() {
	freopen("elis.in","r",stdin);
	freopen("elis.out","w",stdout);
	n = read(); t = read();
	a = read(); b = read(); c = read()-1;
	int x = 1,y = 1;
	if(!check(x+1,y,0,0,0,0) && !check(x,y+1,0,0,0,0)) return printf("Again\n"),0;
	while(x < n || y < n) {
		if(x < n && check(x+1,y,A_,B_,L_,R_)) x ++,putchar('R');
		else y ++,putchar('U');
		A_ += dis(x,y,a,b); B_ += dis(x,y,a+c,b+c);
		L_ += dis(x,y,a,b+c); R_ += dis(x,y,a+c,b);
	} ENDL;
	return 0;
}

这好像是几年前的题了吧🤔

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-03 11:03:35  更:2022-07-03 11:06:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:41:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码