ACwing(春季每日一题题解)


镜子田地(找规律+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;
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值