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;
}