瓦西亚和皮台亚摆放了m个方块。方块被编号为0到m-1(每个号码出现恰好一次)。现在建立一个座标系OX表示地面,OY的方向是竖直向上的。每一方块的左下角有一个座标而且是整点座标。

摆放好的方块一定要是稳定的。稳定的含意是每一个不在地面上的方块在他的下面至少有一个方块与他相接触。可以是共边,也可以是共点的。也就是说如果方块座标为(x,y),要么y=0,或者存在一个方块的座标为(x-1,y-1)或者 (x,y-1) 或者 (x+1,y-1)。

现在瓦西亚和皮台亚要轮流把这些方块一个个拆下来。按照拆下来的顺序从左到右摆成一行,那么方块上面的编号就会组成一个m进制的数字。

拆的过程中,要始终保持剩下的方块稳定。瓦西亚想要最终的数字尽可能大,而皮台亚想要尽可能小,瓦西亚先开始拆。

请帮助计算一下最终形成的数字是多少,结果比较大,输出对 109+9 取余后的结果。

解题报告:

用时:1h10min,1WA1TLE

一开始认为就是开优先队列跑拓扑排序,后来发现度不为0也可以入队,所以只拿了60,然后我想到了正确贪心:

对于瓦西亚的从后往前枚举,直到出现第一个能消除的,皮台亚的同理.

然后打了这个贪心的暴力验证一下,发现是对的,考虑优化:

我们把所有可以消除的点丢入优先队列中,然后每次取出编号最小的,我们需要维护一个\(res[i]\),表示\(i\)最下面还有几个没有消除的点,然后我们检查一个点不合法我们就判断其上面的点是否\(res[i]<=1\),注意每消除一个点就要去更新上面点的\(res\)值,并且如果\(res[i]<=1\)时还要check他上方的点的下方的三个点是否会不合法,这样一个点最多入队三次,均摊复杂度\(O(nlogn)\)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <cstdio>
#include <vector>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=1e5+5,inf=1e9+5,mod=1e9+9;
int n;bool vis[N];
struct node{
int x,y,id;
bool operator <(const node &pp)const{
if(y!=pp.y)return y<pp.y;
return x<pp.x;
}
}a[N];
struct comp{
bool operator ()(int &i,int &j)const{
return i>j;
}
};
priority_queue<int>q;
priority_queue<int,vector<int>,comp>qm;
vector<int>s[N];
int b[N],m=0,num=0,head[N],to[N*3],nxt[N*3],du[N],re[N];
void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
bool check(int x){
if(vis[x])return false;
for(int i=head[x];i;i=nxt[i]){
if(!vis[to[i]] && du[to[i]]<=1)return false;
}
return true;
}
bool ca[N];
void solve(){
bool t=0;int x;
for(int i=1;i<=n;i++){
if(!t){
while(!q.empty()){
if(!ca[q.top()])q.pop();
else break;
}
x=q.top();q.pop();
}
else{
while(!qm.empty()){
if(!ca[qm.top()])qm.pop();
else break;
}
x=qm.top();qm.pop();
}
vis[x]=true;ca[x]=false;
for(int k=0,sz=s[x].size(),u;k<sz;k++){
u=s[x][k];
if(check(u))ca[u]=true,qm.push(u);q.push(u);
}
for(int j=head[x];j;j=nxt[j]){
du[to[j]]--;
for(int k=0,sz=s[to[j]].size(),u;k<sz;k++){
u=s[to[j]][k];
if(!check(u))ca[u]=false;
else{
ca[u]=true;qm.push(u);q.push(u);
}
}
}
re[i]=x-1;t^=1;
}
ll ans=0,mul=1;
for(int i=n;i>=1;i--){
ans+=mul*re[i];
ans%=mod;
mul*=n;mul%=mod;
}
printf("%lld\n",ans);
}
void work()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
a[i].id=i;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)b[++m]=a[i].y;
int sta;
for(int i=1;i<=n;i++){
sta=lower_bound(b+1,b+m+1,a[i].y-1)-b;
for(int j=sta;j<i;j++){
if(a[j].y!=a[i].y-1)break;
if(abs(a[j].x-a[i].x)<=1){
link(a[j].id,a[i].id);du[a[i].id]++;
s[a[i].id].push_back(a[j].id);
}
}
}
for(int i=1;i<=n;i++){
if(check(i))q.push(i),qm.push(i),ca[i]=true;
}
solve();
} int main()
{
work();
return 0;
}

51Nod 1530 稳定方块的更多相关文章

  1. 51nod - 1659 - 数方块 - 简单数学

    https://www.51nod.com/Challenge/Problem.html#!#problemId=1659 随便弄了一下发现公式,然后从cheatsheet抄一抄平方和公式,发现可以提 ...

  2. 51nod 1518 稳定多米诺覆盖(容斥+二项式反演+状压dp)

    [传送门[(http://www.51nod.com/Challenge/Problem.html#!#problemId=1518) 解题思路 直接算不好算,考虑容斥,但并不能把行和列一起加进去容斥 ...

  3. 胡小兔的OI日志3 完结版

    胡小兔的 OI 日志 3 (2017.9.1 ~ 2017.10.11) 标签: 日记 查看最新 2017-09-02 51nod 1378 夹克老爷的愤怒 | 树形DP 夹克老爷逢三抽一之后,由于采 ...

  4. 【51Nod】1519 拆方块 贪心+递推

    [题目]1519 拆方块 [题意]给定n个正整数,\(A_i\)表示第i堆叠了\(A_i\)个石子.每轮操作将至少有一面裸露的石子消除,问几轮所有石子均被消除.\(n \leq 10^5\). [算法 ...

  5. 51nod 80分算法题

    1537:见前几篇. 1627:题意:给定n,m的网格(10^5),初始状态为(1,1),你每次可以瞬移到右下方(不可以同行同列逗留)任何一个方格里,求移动到n,m的方案数. 一句话题解:首先很容易想 ...

  6. 51Nod1518 稳定多米诺覆盖 动态规划 插头dp 容斥原理

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1518.html 题目传送门 - 51Nod1518 题意 51Nod真是个好OJ ,题意概括的真好, ...

  7. 51nod 1206 && hdu 1828 Picture (扫描线+离散化+线段树 矩阵周长并)

    1206 Picture  题目来源: IOI 1998 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  关注 给出平面上的N个矩形(矩形的边平行于X轴 ...

  8. 51nod 1471 小S的兴趣 | 分块 链表

    51nod 1471 小S的兴趣 题面 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题 ...

  9. 51nod 1208 窗上的星星 | 线段树 扫描线

    51nod 1208 Stars In Your Window 题面 整点上有N颗星星,每颗星星有一个亮度.用一个平行于x轴和y轴,宽为W高为H的方框去套星星.套住的所有星星的亮度之和为S(包括边框上 ...

随机推荐

  1. 201621123068 Week04-面向对象设计与继承

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:继承.多态.重载.关键字.父类与子类 1.2 尝试使用思维导图将这些关键词组织起来. 2. 书面作业 1. 面向对象设计(大 ...

  2. iOS开发-继承特征详解

    面向对象的三大特性:封装,继承,多态. 1.继承 继承既能保证类的完整,又能简化代码. 把公共的方法和实例变量写在子类,子类只需要写父类独有的实例变量和方法即可. 继承是面向对象三大特性之一,合理的继 ...

  3. 一、Django的基本用法

    学习Django有一段时间了,整理一下,充当笔记. MVC 大部分开发语言中都有MVC框架 MVC框架的核心思想是:解耦 降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用 ...

  4. 织梦cms/dedecms清理冗余废弃未引用图片方法

    原理描述: 在原有织梦后台菜单中增加"清理冗余图片按钮",实现清理冗余图片的功能. 操作步骤: 1. 打开后台dede\sys_sql_query.php代码 在该文件中搜索如下代 ...

  5. LeetCode & Q88-Merge Sorted Array-Easy

    Array Two Pointers Description: Given two sorted integer arrays nums1 and nums2, merge nums2 into nu ...

  6. ORA-00379 缓冲池 DEFAULT 中无法提供 32K 块大小的空闲缓冲区

    (一)问题 今天在使用Pl/sql developer查看表空间大小的时候,报错误:ORA-00379 缓冲池 DEFAULT 中无法提供 32K 块大小的空闲缓冲区,具体如下图: SQL> s ...

  7. 作业三:模拟 mysql 进行增删改查

    # !/usr/bin/env python3 # _*_coding:utf-8_*_ def help_sql(cmd): if cmd in func_dic.keys(): print('{} ...

  8. SiteMesh在项目中的配置

    SiteMesh在项目中的配置 首先在web.xml里面增加siteMesh的配置: <filter> <filter-name>sitemesh</filter-nam ...

  9. 新概念英语(1-117)Tommy's breakfast

    Lesson 117  Tommy's breakfast 汤米的早餐 Listen to the tape then answer this question. What does she mean ...

  10. 日推20单词 Day02

    1.distinguish v. 区别,辨别 2.tension n. 紧张,不安 3.sympathy n. 同情,慰问 4.admiration n. 羡慕 5.jealousy n. 嫉妒 6. ...