HZOJ 光
一道大模拟,打的我要吐了。
先说一下60%暴力吧,其实模拟光的路线即可,最好还是把边界设为障碍,这样就不用判边界了。最后输出n*m可以骗到10分。
注意不要把n和m弄混(愁死我了)。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<vector>
#define LL long long
#define int LL
using namespace std;
int n,m,k,xs,ys,f;
char te[];
bool map[][];
vector<short> v[][];
void dfs(int x,int y,int num,int fx)
{
// cout<<x<<" "<<y<<" "<<fx<<endl;
if(v[x][y].size()==)num++;
for(int i=;i<v[x][y].size();i++)if(v[x][y][i]==fx){cout<<num<<endl;exit();}
v[x][y].push_back(fx);
if(fx==)
{
if(x==&&y==m)dfs(x,y,num,);
else if(map[x-][y]&&map[x-][y+]&&map[x][y+])dfs(x,y,num,);
else if(x==||(y<m&&map[x-][y]&&map[x-][y+]))dfs(x,y+,num,);
else if(y==m||(x>&&map[x][y+]&&map[x-][y+]))dfs(x-,y,num,);
else if(map[x-][y+])dfs(x,y,num,);
else dfs(x-,y+,num,fx);
}
else if(fx==)
{
if(x==n&&y==m)dfs(x,y,num,);
else if(map[x+][y]&&map[x+][y+]&&map[x][y+])dfs(x,y,num,);
else if(x==n||(y<m&&map[x+][y]&&map[x+][y+]))dfs(x,y+,num,);
else if(y==m||(x<n&&map[x][y+]&&map[x+][y+]))dfs(x+,y,num,);
else if(map[x+][y+])dfs(x,y,num,);
else dfs(x+,y+,num,fx);
}//A
else if(fx==)
{
if(x==n&&y==)dfs(x,y,num,);
else if(map[x+][y]&&map[x+][y-]&&map[x][y-])dfs(x,y,num,);
else if(x==n||(y>&&map[x+][y]&&map[x+][y-]))dfs(x,y-,num,);
else if(y==||(x<n&&map[x][y-]&&map[x+][y-]))dfs(x+,y,num,);
else if(map[x+][y-])dfs(x,y,num,);
else dfs(x+,y-,num,fx);
}
else if(fx==)
{
if(x==&&y==)dfs(x,y,num,);
else if(map[x-][y]&&map[x-][y-]&&map[x][y-])dfs(x,y,num,);
else if(x==||(y>&&map[x-][y]&&map[x-][y-]))dfs(x,y-,num,);
else if(y==||(x>&&map[x][y-]&&map[x-][y-]))dfs(x-,y,num,);
else if(map[x-][y-])dfs(x,y,num,);
else dfs(x-,y-,num,fx);
}
}
signed main()
{
// freopen("ray0.in","r",stdin); cin>>n>>m>>k;
if(n>||m>) {cout<<n*m<<endl;exit();}
int a,b;
for(int i=;i<=k;i++)
{
cin>>a>>b;
if(n<=&&m<=)map[a][b]=;
}
cin>>xs>>ys>>te;
for(int i=;i<=m+;i++)map[][i]=map[n+][i]=;
for(int i=;i<=n+;i++)map[i][]=map[i][m+]=;
if(te[]=='N')
{
if(te[]=='E')f=;
else f=;//W
}
else//S
{
if(te[]=='E')f=;
else f=;//W
}
if(n<=&&m<=)
dfs(xs,ys,,f);
}
暴力
然后说正解(其实就是优化了暴力):
确实有点难以理解,对于光的路线,可以发现其实暴力中间枚举了很多无用的状态,怎么解决呢?
有一个比较简单但是不好想的规律,对于斜线,x+y或x-y不变,那么我们就可以用这个数字代表一条斜线,对于每一条斜线开一个set,将这条斜线上的障碍的x插入,那么二分查找就可以实现快速地转移了。
然而这样递归下去还是比较麻烦的,可以用循环。
再说两个规律:光线经过的路径只可能是环而不是环+链(显然),一条路径中至多出现两次原路返回的情况(这个自己想想也不难,其实是我不会证)。
所以循环处理即可,具体见代码。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
#define LL long long
#define MAXN 200010
#define MP(a,b) make_pair(a,b)
#define ma(x) memset(x,0,sizeof(x))
using namespace std;
int n,m,k;
int xs,ys;char te[];
LL ans=;
struct rec{int x,y,d;};
set<int> s1[MAXN],s2[MAXN];
map<pair<int,int>,bool>mp;
int getid(int x,int y,int d){return d==?x-y+m+:x+y;}
bool same(rec a,rec b){if(a.x==b.x&&a.y==b.y&&a.d==b.d)return ;return ;}
bool check(int x,int y){return mp[MP(x,y)];}
void add(int x,int y)
{
s1[getid(x,y,)].insert(x);
s2[getid(x,y,)].insert(x);
mp[MP(x,y)]=;
}
pair<rec,int> dfs(rec u)
{
rec re;
set<int>::iterator it;
if(u.d==)
{
it=s1[getid(u.x,u.y,)].lower_bound(u.x);it--;
re.x=u.x-(abs(*it-u.x)-);
re.y=u.y-(abs(*it-u.x)-);
if(check(re.x-,re.y)&&check(re.x,re.y-))re.d=;
else if(check(re.x-,re.y))re.d=,re.y--;
else if(check(re.x,re.y-))re.d=,re.x--;
else re.d=;
}
if(u.d==)
{
it=s2[getid(u.x,u.y,)].lower_bound(u.x);it--;
re.x=u.x-(abs(*it-u.x)-);
re.y=u.y+(abs(*it-u.x)-); if(check(re.x-,re.y)&&check(re.x,re.y+))re.d=;
else if(check(re.x-,re.y))re.d=,re.y++;
else if(check(re.x,re.y+))re.d=,re.x--;
else re.d=;
}
if(u.d==)
{
it=s1[getid(u.x,u.y,)].lower_bound(u.x);
re.x=u.x+(abs(*it-u.x)-);
re.y=u.y+(abs(*it-u.x)-); if(check(re.x+,re.y)&&check(re.x,re.y+))re.d=;
else if(check(re.x+,re.y))re.d=,re.y++;
else if(check(re.x,re.y+))re.d=,re.x++;
else re.d=;
}
if(u.d==)
{
it=s2[getid(u.x,u.y,)].lower_bound(u.x);
re.x=u.x+(abs(*it-u.x)-);
re.y=u.y-(abs(*it-u.x)-); if(check(re.x+,re.y)&&check(re.x,re.y-))re.d=;
else if(check(re.x+,re.y))re.d=,re.y--;
else if(check(re.x,re.y-))re.d=,re.x++;
else re.d=;
}
return MP(re,abs(*it-u.x));
}
bool judge(rec u)
{
rec re=u;
do
{
pair<rec,int> cur=dfs(u);
ans+=cur.second;
switch(cur.first.d)
{
case :if(u.d==)return ;break;
case :if(u.d==)return ;break;
case :if(u.d==)return ;break;
case :if(u.d==)return ;break;
}
u=cur.first;
}while(!same(re,u));
return ;
} signed main()
{
// freopen("in.txt","r",stdin); cin>>n>>m>>k;
for(int i=;i<=m+;i++)add(,i),add(n+,i);
for(int i=;i<=n;i++) add(i,),add(i,m+);
int a,b;
for(int i=;i<=k;i++)
{
cin>>a>>b;
add(a,b);
}
int f;
cin>>xs>>ys>>te;
if(te[]=='N')
{
if(te[]=='E')f=;
else f=;//W
}
else//S
{
if(te[]=='E')f=;
else f=;//W
}
rec st={xs,ys,f};
st=dfs(st).first;
if(!judge(st))//判断第一次反向
{
ans--;
switch(st.d)
{
case :st.d=;break;
case :st.d=;break;
case :st.d=;break;
case :st.d=;break;
}
judge(st);
}
cerr<<ans<<endl;
cout<<ans<<endl;
}
HZOJ 光的更多相关文章
- 搭建自己私有的PKM系统,各家PKM大比拼。。附:构建自己熟悉的基础Docker,破解联通光猫
Docker这容器真是很好玩!干啥都想上docker了,快疯了. 这不,最近wiz笔记开始收费,很是不爽,需要寻求新的PKM系统了.备选及落选理由如下: wiz笔记 -- 好用,顺手.要开始收费了,不 ...
- webform 光棒效果,删除操作弹出确定取消窗口
鼠标移入onmouseover和鼠标移出onmouseout,代码里没大写我这也就不大写了.那首先,我们得获取Class为tr_item里的所有东西,也就是项标签里的数据.然后呢,我们定义一个oldC ...
- 兼容可控硅调光的一款LED驱动电路记录
1.该款电路为兼容可控硅调光的LED驱动电路,采用OB3332为开关控制IC,拓扑方案为Buck: 2.FB1:磁珠的单位是欧姆,而不是亨利,这一点要特别注意.因为磁珠的单位是按照它在某一频率 产生的 ...
- Arduino 极速入门系列 - 光控灯(3) - 光敏电阻、与电阻分压那些事
继续是讲解基础原理,新手专用部分.这次讲光敏电阻,和用电阻分压.光电元器件有好几种,其中测光相关的元器件,常见的有光敏三极管和光敏电阻,我们这次光控灯用光敏电阻.在我们光控灯里面,将会使用它搭建出分压 ...
- Arduino 极速入门系列 - 光控灯(2) - 关于开关,上拉、下拉电阻那些事
接上篇,这次继续讲解光控灯的另外两个组成部分 - 开关和光敏电阻,光控灯里面将会有自锁开关按钮和光敏电阻.这此主要给新玩电子的朋友解释一下开关按钮的做法. 开关按钮的引脚电平读取问题 - 新手专用 我 ...
- Arduino 极速入门系列 - 光控灯(1)- 关于理论和 LED 那些事
点个 LED 闪亮好像太单调,这次来个光控 LED 灯.这个其实不需要 Arduino 也能做,这次只是用来演示一下 PWM 在 Arduino 里面的做法.PWM 原理后面会解释.这次用充电宝提供 ...
- 关于紫光a5扫描仪的安装
同事需要扫描写东西,从别的机器上搬来紫光a5的扫描仪,不会安装,需要帮忙. 插上扫描仪,win7提示发现新硬件,开始自动安装驱动.等了一会儿,提示无法安装,看来得手工寻找驱动来安装了.上网搜索a5的驱 ...
- 实战之中兴ZXHN F460光猫破解超级密码+开启无线路由功能
本文面向小白用户,即使你不懂电脑看完你也会破解光猫,网上有些文章的操作方法是错误的.按照我这篇文章,只要型号对,那么肯定没问题!电信光纤入户,家里用的是电信送的中兴查看 ZXHN F460 中的全部文 ...
- Atitit.iso格式蓝光 BDMV 结构说明
Atitit.iso格式蓝光 BDMV 结构说明 1. Iso是个复合文件1 2. Iso内部格式如下1 2.1. Bdmv文件夹格式 BDMV(Blu-ray Disk Movie.BD-MV),为 ...
随机推荐
- jnhs[未解决]无法使用选定的hibernate配置文件建立数据库连接.请验证hibernate.cfg.xml中的数据库连接详情信息
工程可以正常的使用读写数据库,当然model和model.hbm.xml文件是自己写的. 解决中
- Boost.Asio基础
http://www.voidcn.com/article/p-exkmmuyn-po.html http://www.voidcn.com/article/p-xnxiwkrf-po.html ht ...
- 前后端分离后API交互如何保证数据安全性
前后端分离后API交互如何保证数据安全性? 一.前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC ...
- 2019.7.29 NOIP模拟测试10 反思总结【T2补全】
这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...
- JS中int和string的转换
1.int型转换成string型 (1) var x=100 a = x.toString() (2) var x=100; a = x +"& ...
- POJ1182 NOI2001 食物链
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 77428 Accepted: 23067 Description ...
- Vue--系统指令(基础)
Vue概念:vue是mvvm模式的,直接操作dom开销较大,先获取dom,修改里边的内容,但是用vue的话,直接视图和模型绑定,不管是视图的数据发生改变还是模型的数据发生改变,其都是关联的,不需要直接 ...
- OpenLayers添加和删除控件
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- IntelliJ IDEA 下的svn配置及使用的非常详细的图文总结(转)
IntelliJ IDEA使用教程 (总目录篇) 首先,使用的时候,自己得先在电脑上安装个小乌龟.也就是svn啦. 第一步安装小乌龟. 如下: 具体安装好像没什么具体要求,一路next,就好. 如上图 ...
- Django框架Day3------之Models
一.Django models字段类型清单: AutoField:一个自动递增的整型字段,添加记录时它会自动增长.你通常不需要直接使用这个字段:如果你不指定主键的话,系统会自动添加一个主键字段到你的m ...