22/7/20

1,Dragon slayer;2,Alice and Bod;3,Laser;


1,Dragon slayer;

题意:给出英雄坐标和恶龙坐标还有一些墙的两个端点(墙是一条线),英雄碰到墙需要用魔法穿过,并使得该墙消失,问到达恶龙需要最少几次魔法;

英雄坐标和恶龙坐标(x,y)都需+0.5;也就是在格中;第一次碰到这样的形式,被卡住了了;

题解的表示就是把纵墙都放到格子左边的线上,横墙都放到格子下边的线上;这样人物在上下左右移动是,就可以判断如何穿过来的;(这个点还是要掌握一下);

做法:枚举墙的状态,然后根据墙的状态走地图,能走到,则更新答案;

枚举状态可以dfs递归枚举,也可以状态压缩枚举;

走地图bfs,dfs均可;

我用的是dfs枚举+bfs走地图;(dfs枚举时可以优化搜索顺序和最优性剪枝);

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=(a);i<(n);++i) 
#define rep2(i,a,n) for( int i=(a);i<=(n);++i) 
#define per1(i,n,a) for( int i=(n);i>(a);i--) 
#define per2(i,n,a) for( int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define dbug(y) cout<<(#y)<<"\n"
#define yi first
#define er second
#define INF 0x3f3f3f3f
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
#define pi 3.14159265358979323846
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<pair<int,int>,pair<int,int>>PIIII;
typedef pair<long long,long long> PLL;
typedef double dob;
typedef pair<dob,dob> PDD;
const int N=20;
struct node
{
    int x1,y1,x2,y2;
}wall[N];
int mp[N][N];
int st_wall[N];
int L_wall[N][N],D_wall[N][N];
int n,m,k,x3,y3,xt,yt;
int ans=INF;
PII q[N*N];
bool bfs()
{
    memset(mp,0,mp);
    memset(L_wall,0,L_wall);
    memset(D_wall,0,D_wall);
    int hh=0,tt=0;
    q[0]={x3,y3};
    mp[x3][y3]=1;
    rep1(i,0,k)
    {
        if(st_wall[i])
        {
            int x1=wall[i].x1,x2=wall[i].x2,y1=wall[i].y1,y2=wall[i].y2;
            if(x1==x2)
            {
                rep1(col,y1,y2)
                {
                    L_wall[x1][col]=1;
                }
            }
            else
            {
                rep1(row,x1,x2)
                {
                    D_wall[row][y1]=1;
                }
            }
        }
    }
    while (hh<=tt)
    {
        auto s=q[hh++];
        int x=s.first,y=s.second;
        if(x==xt&&y==yt)
        {
            return 1;
        }
        if(x>=1&&L_wall[x][y]==0&&!mp[x-1][y])
        {
            q[++tt]={x-1,y};
            mp[x-1][y]=1;
        }
        if(x+1<n&&L_wall[x+1][y]==0&&!mp[x+1][y])
        {
            q[++tt]={x+1,y};
            mp[x+1][y]=1;
        }
        if(y>=1&&D_wall[x][y]==0&&!mp[x][y-1])
        {
            q[++tt]={x,y-1};
            mp[x][y-1]=1;
        }
        if(y+1<m&&D_wall[x][y+1]==0&&!mp[x][y+1])
        {
            q[++tt]={x,y+1};
            mp[x][y+1]=1;
        }
    }
    return 0;
}
void dfs(int u,int num)
{
    if(num>=ans)return;
    if(u==k)
    {
        if(bfs())ans=num;
        return;
    }
    st_wall[u]=1;//墙存在;
    dfs(u+1,num);
    st_wall[u]=0;//墙不存在;
    dfs(u+1,num+1);

}
void solve()
{
    cin>>n>>m>>k>>x3>>y3>>xt>>yt;
    ans=INF;
    memset(st_wall,0,st_wall);
    rep1(i,0,k)
    {
        int x1,y1,x2,y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1==x2)
        {
            if(y1>y2)swap(y1,y2);
            wall[i]={x1,y1,x2,y2};
        }
        else 
        {
            if(x1>x2)swap(x1,x2);
            wall[i]={x1,y1,x2,y2};
        }
    }
    dfs(0,0);
    cout<<ans<<endl;
}
signed main()
{
    quick_cin();
    T_solve();
    return 0;
}

2,Alice and Bob

思路:从2个1开始发现A必赢,然后4个2就必能得出2个1,同理8个3必能得出4个2,。。但是对于2 2 2 3 3来说,A也是必赢的,由此可以得出,后面的数对前面数的贡献个数是ai/2,最终只要推出来有0,A就赢,否则就是Bob;

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=(a);i<(n);++i) 
#define rep2(i,a,n) for( int i=(a);i<=(n);++i) 
#define per1(i,n,a) for( int i=(n);i>(a);i--) 
#define per2(i,n,a) for( int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define dbug(y) cout<<(#y)<<"\n"
#define yi first
#define er second
#define INF 0x3f3f3f3f
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) we[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
#define pi 3.14159265358979323846
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<pair<int,int>,pair<int,int>>PIIII;
typedef pair<long long,long long> PLL;
typedef double dob;
typedef pair<dob,dob> PDD;
const int N=1e6+10;
int a[N];
int n;
void solve()
{
    cin>>n;
    rep2(i,0,n)cin>>a[i];
    per2(i,n,1)
    {
        a[i-1]+=a[i]/2;
    }
    if(a[0])dbug(Alice);
    else dbug(Bob);
}
signed main()
{
    quick_cin();
    T_solve();
    return 0;
}

3,Laser;

首先拿一个点在他所在的横线上找,找到第一个不在该线上的点,那么通过该点,可以确定答案一定在该点能延伸的情况与横线的3个交点上;

 如图所示;

然后所在横线可以是x,可以是y也可以是两条斜对角线;

把4种情况都枚举出来,然后枚举每种情况找出来的3点;

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=(a);i<(n);++i) 
#define rep2(i,a,n) for( int i=(a);i<=(n);++i) 
#define per1(i,n,a) for( int i=(n);i>(a);i--) 
#define per2(i,n,a) for( int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define dbug(y) cout<<(#y)<<"\n"
#define yi first
#define er second
#define INF 0x3f3f3f3f
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) we[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
#define pi 3.14159265358979323846
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<pair<int,int>,pair<int,int>>PIIII;
typedef pair<long long,long long> PLL;
typedef double dob;
typedef pair<dob,dob> PDD;
const int N=1e5+10;
int a[N],b[N],x[N],y[N];
int n;
bool pd(int x,int y)
{
    if(!x||!y||x==y||x+y==0)return 1;
    return 0;
}
bool check(int xx,int yy)
{
    rep2(i,1,n)
    {
        if(!pd(xx-x[i],yy-y[i]))return 0;
    }
    return 1;
}
bool check()
{
    int f=1;
    rep2(i,2,n)
    {
        if(x[i]==x[1])continue;
        f=0;
        if(check(x[1],y[i]))return 1;
        if(check(x[1],y[i]+(x[i]-x[1])))return 1;
        if(check(x[1],y[i]-(x[i]-x[1])))return 1;
        break;
    }
    if(f)return 1;
    return 0;
}
void solve()
{
    cin>>n;
    rep2(i,1,n)cin>>a[i]>>b[i];
    rep2(i,1,n)x[i]=a[i],y[i]=b[i];
    if(check())
    {
        dbug(YES);
        return;
    }
    rep2(i,1,n)x[i]=b[i],y[i]=a[i];
    if(check())
    {
        dbug(YES);
        return;
    }
    rep2(i,1,n)x[i]=a[i]+b[i],y[i]=a[i]-b[i];
    if(check())
    {
        dbug(YES);
        return;
    }
    rep2(i,1,n)x[i]=a[i]-b[i],y[i]=a[i]+b[i];
    if(check())
    {
        dbug(YES);
        return;
    }
    dbug(NO);
}
signed main()
{
    quick_cin();
    T_solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dull丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值