【CF 520D】Cubes
怎么说呢……英语阅读题+超级大模拟……
最重要的是知道怎么出来的数据。。。题意好懂
xy坐标内给出几个单位正方形 以正方形左下点坐标给出
y=0为地面 正方形下面或者左右下方至少存在一个正方形他才能稳定。。
正方形按0~m-1标号 每次只能取出不影响整体结构的正方形
甲乙玩一个游戏 交替取正方形 每取下一个按从左到右的顺序排好 得到一个大数 重点来了!
取出的数是m进制 转换为十进制是最终结果 甲希望结果最大 乙希望结果最小 问结果为多少 甲先取
题意明白了模拟就行 开两个优先队列分别给甲(递减)乙(递增) 再开个Map用来查询正方形编号
先把所有能取的正方形编号存进去 每取出一个看他左下 下 右下有没有正方形并判断去除这些正方形影不影响剩余结构 不影响就存入队列 同时判断左上 上 右上存不存在正方形 并看取走这个正方形后他们下面其他的正方形还可不可取 不可取的话标记下 下次队列遍历到不要取走 最后把m进制转换二进制输出即可
代码如下:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <list>
#include <map>
#define mod 1000000009
#define ll long long
//#define Debug
using namespace std;
pair <int,int> sq[100005];
priority_queue <int,vector<int>,greater<int> > small;
priority_queue <int,vector<int>,less<int> > big;
map <pair<int,int>,int> gt;
int has[100005];//-1 图内/不能选择 1队列内 0已组合
ll pex[100005],sum;
void Init(int m)
{
pex[1] = 1;
for(int i = 2; i <= m; ++i) pex[i] = (pex[i-1]*m)%mod;
memset(has,-1,sizeof(has));
}
bool hs(int x,int y)
{
return (gt.count(pair<int,int> (x,y)) && has[gt[pair<int,int> (x,y)]] != 0);
}
bool Stable(int x,int y)
{
if(!hs(x,y)) return true;
int t = 0;
if(hs(x-1,y-1)) t++;
if(hs(x,y-1)) t++;
if(hs(x+1,y-1)) t++;
if(t >= 2) return true;
return false;
}
void Add(int x,int y,int i)
{
if(has[i] == -1 && Stable(x+1,y+1) && Stable(x,y+1) && Stable(x-1,y+1))
{
#ifdef Debug
printf("*%d\n",i);
#endif // Debug
big.push(i);
small.push(i);
has[i] = 1;
}
}
void Clr(int t,int s)
{
#ifdef Debug
printf("%d\n",t);
#endif
sum = (sum + (t*pex[s])%mod)%mod;
int x = sq[t].first;
int y = sq[t].second;
has[t] = 0;
gt.erase(pair<int,int> (x,y));
for(int i = 1; i >= -1; --i)
if(hs(x+i,y+1) && !Stable(x+i,y+1))
{
if(i)
{
if(hs(x+i*2,y)) has[gt[pair<int,int> (x+i*2,y)]] = -1;
if(hs(x+i,y)) has[gt[pair<int,int> (x+i,y)]] = -1;
}
else
{
if(hs(x+1,y)) has[gt[pair<int,int> (x+1,y)]] = -1;
if(hs(x-1,y)) has[gt[pair<int,int> (x-1,y)]] = -1;
}
}
for(int i = 1; i >= -1; --i)
if(hs(x+i,y-1)) Add(x+i,y-1,gt[pair<int,int> (x+i,y-1)]);
}
int Vasa()
{
int t = big.top();
big.pop();
while(has[t] != 1)
{
t = big.top();
big.pop();
}
#ifdef Debug
printf("bs%d\n",big.size());
#endif
return t;
}
int Peta()
{
int t = small.top();
small.pop();
while(has[t] != 1)
{
t = small.top();
small.pop();
}
#ifdef Debug
printf("ss%d\n",small.size());
#endif
return t;
}
int main()
{
int m,i,x,y,t;
scanf("%d",&m);
Init(m);
for(i = 0; i < m; ++i)
{
scanf("%d %d",&x,&y);
sq[i] = pair<int,int> (x,y);
gt.insert(pair<pair<int,int>,int> (pair<int,int>(x,y),i));
}
for(i = 0; i < m; ++i)
{
x = sq[i].first;
y = sq[i].second;
Add(x,y,i);
}
sum = 0;
for(i = 0; i < m; ++i)
{
if(i&1) t = Peta();
else t = Vasa();
Clr(t,m-i);
}
printf("%lld\n",sum);
return 0;
}