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
- #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
int,int>,pair<int,int>>PIIII; - typedef pair<long long,long long> PLL;
- typedef double dob;
- typedef pair
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
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
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<
- }
- 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
- #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
int,int>,pair<int,int>>PIIII; - typedef pair<long long,long long> PLL;
- typedef double dob;
- typedef pair
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
- #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
int,int>,pair<int,int>>PIIII; - typedef pair<long long,long long> PLL;
- typedef double dob;
- typedef pair
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;
- }