镜子田地(找规律+dfs)
题目原链接
题目分析:镜子有两种放置方式 ‘/’ 和 ‘\’
将被镜子分为的上下看做两个节点,根据光路的可逆性,可以得出,每个节点的度数最大为2,故不会在外部射入到内部然后内部出现环,我们需要去枚举光路,因为保证光路是垂直射入,所以如图枚举
我们需要标记每一步的方向,因为镜子的存在会导致我们下一步的方向是会发生改变的,要根据遇到的镜子分析
1.遇到 ‘ / ’
2.遇到 ‘ \ ’
详细看代码
#include<bits/stdc++.h>
#define ll long long
#define PI 3.141592653589793
#define E 2.718281828459045
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FO( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define lowbit(a) ((a)&-(a))
#define PII pair<ll ,ll >
#define ft first
#define sd second
typedef unsigned long long ull;
const ll mod=10007;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll Max=1e3+10;
using namespace std;
ll t,n,m,l,k;
ll ans;
char mp[Max][Max];
ll mov[][2]={-1,0,0,1,1,0,0,-1};
/*queue<ll> q;
stack<ll> s;
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;*/
ll dfs(ll x,ll y,ll d)
{
if(x<1||x>n||y<1||y>m)return 0;
if(mp[x][y]=='/')d^=1;
else d^=3;
return dfs(x+mov[d][0],y+mov[d][1],d)+1;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
cin>>mp[i][j];
for(ll i=1;i<=n;i++)
{
ans=max(ans,dfs(i,1,1));
ans=max(ans,dfs(i,m,3));
}
for(ll i=1;i<=m;i++)
{
ans=max(ans,dfs(1,i,2));
ans=max(ans,dfs(n,i,0));
}
cout<<ans<<endl;
return 0;
}
镜子(枚举+回溯(恢复现场))
题目原链接
题目大意:给定n个坐标,每个坐标有一面镜子,镜子是‘ / ’,或者 ‘ \ ’,然后给定一个定点,问能否从原点沿平行于x轴或者y轴射出一条光线通过镜子的反射到达定点,你有一次翻转镜子的机会,若不需要翻转则输出0,可以通过翻转到达,输出第一次翻转就可以到达的镜子的序号,若无法到达输出-1
思路:枚举翻转哪块镜子,判断是否可以到达,没块镜子可以分为两个节点,跟上面的题差不多,然后这个里面是有可能形成环的
对于n块镜子,就有2n个节点,若有2(n+1)条边就会有环,直接return false;详细看代码
#include<bits/stdc++.h>
#define ll long long
#define PI 3.141592653589793
#define E 2.718281828459045
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FO( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define lowbit(a) ((a)&-(a))
#define PII pair<ll ,ll >
#define ft first
#define sd second
typedef unsigned long long ull;
const ll mod=10007;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll Max=1e6+10;
using namespace std;
ll mov[][2]={0,1,1,0,0,-1,-1,0};
ll t,n,m,l,k,x,y;
ll ans;
struct node
{
ll x,y;
char c;
};
node q[Max];
void turn(char &w)
{
if(w=='/')w='\\';
else w='/';
}
bool check()
{
ll k=0;//第几块镜子
ll d=1;//方向
for(ll i=0;i<2*(n+1);i++)
{
ll id=-1/*哪块镜子*/,len=INF;//两个镜子的距离
for(ll j=1;j<=n+1;j++)
{
if(k==j)continue;//同一面镜子
if(q[k].x+mov[d][0]*abs(q[k].x-q[j].x)!=q[j].x)continue;//不在同一条横线上
if(q[k].y+mov[d][1]*abs(q[k].y-q[j].y)!=q[j].y)continue;//不在同一条竖线上
t=abs(q[k].x-q[j].x)+abs(q[k].y-q[j].y);//距离下一个镜子的距离
if(t<len)len=t,id=j;//更新距离和镜子编号
}
if(id==-1)return false;//无解
if(id==n+1)return true;
k=id;//更新第几块镜子
if(q[id].c=='/')d^=1;
else d^=3;//处理方向
}
return false;
}
/*queue<ll> q;
stack<ll> s;
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;*/
int main()
{
ios::sync_with_stdio(false);
cin>>n>>q[n+1].x>>q[n+1].y;
for(ll i=1;i<=n;i++)
{
cin>>q[i].x>>q[i].y>>q[i].c;
}
if(check())
{
cout<<0<<endl;
return 0;
}
for(ll i=1;i<=n;i++)
{
turn(q[i].c);
if(check())
{
cout<<i<<endl;
return 0;
}
turn(q[i].c);//恢复现场
}
cout<<-1<<endl;
return 0;
}
找到牛!(思维+遍历)
题目原链接
思路;遍历字符串,记录 (( 的个数,当碰到 )) 时,就加上 )) 前面出现的 (( 的个数,因为 )) 前面的 (( 都可以匹配
#include<bits/stdc++.h>
#define ll long long
#define PI 3.141592653589793
#define E 2.718281828459045
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FO( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define lowbit(a) ((a)&-(a))
#define PII pair<ll ,ll >
#define ft first
#define sd second
typedef unsigned long long ull;
const ll mod=10007;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll Max=1e4+10;
using namespace std;
ll t,n,m,l,k;
ll ans;
/*queue<ll> q;
stack<ll> s;
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;*/
int main()
{
ios::sync_with_stdio(false);
string s;
cin>>s;
l=s.size();
ll sum=0;
for(ll i=0;i<l-1;i++)
{
if(s[i]==')'&&s[i+1]==')')ans+=sum;//后腿
else if(s[i]=='('&&s[i+1]=='(')sum++;//前腿
}
cout<<ans<<endl;
return 0;
}