D - Step Up Robot
大意:
格子阶梯,给定一步可以走的步数选择,不能后退,问从0开始能否走到n
思路:
dfs+记忆化
code
#include
using namespace std;
#define ll int
#define endl '\n'
const ll N=2e5+10;
ll n,m;
ll a,o;
ll mas[N];
ll num[N];
ll vis[N];
ll ans[N];
bool dfs(ll id)
{
if(ans[id]!=-1) return ans[id];
if(vis[id]) return 0;
if(id>o) return 0;
if(id==o) return 1;
for(int i=1;i<=n;++i)
{
if(dfs(id+mas[i])) return ans[id]=1;
}
return ans[id]=0;
}
void solve()
{
cin>>n;
memset(ans,-1,sizeof ans);
for(int i=1;i<=n;++i) cin>>mas[i];
cin>>m;
for(int i=1;i<=m;++i)
{
cin>>a;
vis[a]=1;
}
cin>>o;
cout<<(dfs(0)?"Yes":"No")<>t;while(t--)
solve();
return 0;
}
E - Swap Places
大意:
一张简单图,每一个点有一个颜色(1或0),两个点从分别从1和n出发,同时走下一步,且两者下一步的颜色必须不同,问能否实现分别到达n和1.如果可以,求最小步数
思路:
因为点数和边数都不多,我们可以直接记录两个点的中间状态,然后bfs一下就可以了
初始状态是(1,n),最终状态是(n,1)
code
#include
using namespace std;
#define ll long long
#define endl '\n'
#define mk make_pair
const ll N=2010;
const ll inf=1e9;
ll n,m;
vector vt[N];
ll mp[N][N];
ll col[N];
void bfs()
{
queue> q;
q.push(mk(1,n));
mp[1][n]=0;
while(!q.empty())
{
ll x=q.front().first;
ll y=q.front().second;
q.pop();
for(auto xx:vt[x])
{
for(auto yy:vt[y])
{
if(mp[xx][yy]!=inf) continue;
if(col[xx]==col[yy]) continue;
mp[xx][yy]=mp[x][y]+1;
q.push(mk(xx,yy));
if(mp[n][1]!=inf) return;
}
}
}
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;++i) cin>>col[i],vt[i].clear();
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j) mp[i][j]=inf;
}
for(int i=1;i<=m;++i)
{
ll a,b;
cin>>a>>b;
vt[a].push_back(b);
vt[b].push_back(a);
}
bfs();
cout<<(mp[n][1]!=inf?mp[n][1]:-1)<>t;while(t--)
solve();
return 0;
}
F - Teleporter Takahashi
大意:
二维平面,给定起点A和终点B,要求从A走到B。
规则如下,每次在一个选定区域内选择一个坐标均为整数的点C,移动到关于点C对称的点。
如果能实现,输出每次操作选定的对称点
选定区域:R:={(x,y)∣a−0.5≤x≤b+0.5,c−0.5≤y≤d+0.5}
思路:
为什么我会想到投影的方向去。。。)
不难发现,如果我们能够实现每次只改变横坐标/纵坐标的话,是可以贪心解决该问题的。更进一步,在不改变横坐标的情况下,如果连续两次选择的点的纵坐标相差=1,那么最后的实际效果是纵坐标变化=2,这是改变的最小差值。所以一个能实现的前提就是:起终点的坐标差值为偶数
接着,每次改变2的话,贪心一下就好了。因为如果我们只改变纵坐标的话,第一次选(a,c),第二次选(a,c+1),可以发现横坐标会回到原位
但是还有a=b或者c=d的情况(wa烂了)
自行体会吧,有些坑还是得自己去踩
code
#include
using namespace std;
#define ll long long
#define endl '\n'
#define mk make_pair
const ll N=2010;
const ll inf=1e9;
ll n,m;
ll a,b,c,d;
ll sx,sy,tx,ty;
bool f1,f2;
void solve()
{
cin>>sx>>sy>>tx>>ty;
cin>>a>>b>>c>>d;
if(abs(sx-tx)%2||abs(sy-ty)%2)
{
cout<<"No"<0)
{
cout<0)
{
cout<>t;while(t--)
solve();
return 0;
}
G
详见我的另一篇博客
Ex
不会