Codeforce DIV2 614 SZU的cf集训round1 C ~ D

C. NEKO’s Maze Game

位运算+数据结构维护

题目大意:就是在一个2*n的迷宫里面,在任意时刻就会有一个位置从地面变成岩浆,或者从岩浆变成地面。问你在任意时刻你是否可以从(1,1)点跑到(2,n)这个点

思路通过观察可知 如果同一行有两个岩浆点,或者相邻的两行的对角线上都是岩浆那么都是不可行的,那么我们可以将每一行看成以一个二进制数如果这个位置是岩浆的化就标为1,否则就是0,类似开关的转化,那么就要用异或运算 1 ^ 1=0,0 ^ 1=1; 对于判断是否通路就用或运算,如果两行取或运算的结果为3的化那么就不能过,我们再定义一个map去存储哪些位置堵了,如果不堵了再将它删掉

下面看代码

#include<iostream>
#include<cstdio> 
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
#include<bitset>
#define f first
#define s second
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
using namespace std;
 
typedef unsigned long long ULL;
typedef pair<int,int> PII;
const int mod = 998244353; 
const int N = 1e5 + 100;
PII p[N];
int h[N],n,m,T,s;
int Xor[N];
bool flag;
map<PII,int> ung;
int main()
{
    cin >> n >> T;
    for(int i = 1; i <= T; ++ i)
    {
        flag = false;
        cin >> p[i].f >> p[i].s;
        h[p[i].s] ^= (1 << (2 - p[i].f)); 
        Xor[p[i].s] = h[p[i].s] | h[p[i].s - 1];
        Xor[p[i].s + 1] = h[p[i].s + 1] | h[p[i].s];
        if(Xor[p[i].s] == 3 || Xor[p[i].s + 1] == 3)
        {
            puts("No");
            if(Xor[p[i].s] == 3)
                ung[{p[i].s - 1,p[i].s}] = 1;
            if(Xor[p[i].s + 1] == 3)
                ung[{p[i].s,p[i].s + 1}] = 1;
                flag = true;
        }
        
        if(Xor[p[i].s + 1] != 3)
        {
            if(ung.find({p[i].s,p[i].s + 1}) != ung.end())
            ung.erase({p[i].s,p[i].s + 1});
        }
            
        if(Xor[p[i].s] != 3)
        {
            if(ung.find({p[i].s - 1,p[i].s}) != ung.end())
            ung.erase({p[i].s - 1,p[i].s});
        }
        if(flag) continue;
            if(!ung.empty()) puts("No");
            else puts("Yes");
    }
}

D. Aroma’s Search

【题目大意】 有一个无限的网格,有一些网格有数据,这些网格坐标满足 第一个坐标为 (x0, y0) 第i个坐标为(ax⋅x[i−1] + bx, ay⋅ y[i−1] + by) 你从(xs, xy)出发,每向相邻的格子移动一下会花费1s时间,总时间为t,问你能拿到的最多数据是多少,每个数据仅能拿走一次

思路:通过递推式可以发现你最远到达就60多个点,

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=105;
int x[maxm],y[maxm];
int ax,ay,bx,by;
int xs,ys,t;
int cnt;
int d(int a,int b,int x,int y){
    return abs(a-x)+abs(b-y);
}
signed main(){
    cin>>x[0]>>y[0]>>ax>>ay>>bx>>by;
    cin>>xs>>ys>>t;
    while(x[cnt]-xs<t&&y[cnt]-ys<t){
        cnt++;
        x[cnt]=x[cnt-1]*ax+bx;
        y[cnt]=y[cnt-1]*ay+by;
    }
    int ans=0;
    for(int i=0;i<=cnt;i++){
        for(int j=i;j<=cnt;j++){
            if(j-i+1<=ans)continue;
            int temp=min(d(xs,ys,x[i],y[i]),d(xs,ys,x[j],y[j]));
            temp+=d(x[i],y[i],x[j],y[j]);
            if(temp<=t){
                ans=j-i+1;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值