Codeforces Round #614 (Div. 2)(A~D)

题目链接

A. ConneR and the A.R.C. Markland-N(思维)

分析

  • 题意
  1. 有一个n层的楼,每一层都有一个饭店,又给了k个数,表示那些层的饭店是关着的,现在一个人在s层问最少经过多少个楼梯就可以到达一个饭店
  • 思路
  1. 就是从那个人所在的那一层开始,逐渐向外边楼层,开始枚举,一旦正枚举的楼层,没在k数字中出现,那么答案就到这一层所需要经过的楼梯数

代码

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define db double
#define INF 0x3f3f3f3f
#define mod 998244353
const int mxn = 2e5 + 10;


int ar[mxn];
map<int, int> mp;

int main()
{
    /* fre(); */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        mp.clear();
        int n, s, k;
        scanf("%d %d %d", &n, &s, &k);
        for(int i = 1; i <= k; i ++)
        {
            scanf("%d", &ar[i]);
            mp[ar[i]] ++;
        }
        for(int i = 0; ; i ++)
        {
            if(s + i <= n && mp[s + i] == 0)
            {
                printf("%d\n", i);
                break;
            }
            if(s - i >= 1 && mp[s - i] == 0) 
            {
                printf("%d\n", i);
                break;
            }
        }
    }

    return 0;
}


B. JOE is on TV!(简单规律题)

分析

  • 思路
  1. 直接根据题目的意思分别举例几个简单的例子,找一下规律

代码

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define db double
#define INF 0x3f3f3f3f
#define mod 998244353
const int mxn = 2e5 + 10;

int main()
{
    /* fre(); */
    int n;
    scanf("%d", &n);
    db  ans = 0;
    for(int i = 1; i <= n; i ++)
    {
        ans += (1.0/i);
    }
    printf("%f\n", ans);

    return 0;
}


C. NEKO’s Maze Game

分析

  • 题意
  1. 给我们一个2*n的表格,现在一个人要从(1,1)走到(2,n),这个地图的表格有两个状态:可走状态、不可走状态(刚开始的时候地图表格均为 可行走状态),给我们q个时刻,第i个时刻 ( x i , y i ) (x_i,y_i) 这个表格上状态发生改变,我们认为 1个时刻就可以从起点到终点(如果路走的通的话),,对于每个时刻如果能走到终点输出YES否则NO
  • 思路
  1. 询问了q个时刻,是否能够到达终点,当我考虑当前这个时刻能否到达终点是建立在 上一个时刻的地图的情况 + 这个时刻地图的改变 的基础上的,所以我们可以在不断维护前一刻的基础上得到当前时刻的答案
  2. 还有我们要注意到所给的地图是一个 2*n 的地图,产生无法通过的情况是:在第一行与第二行的存在两个表格 ( 1 , y 1 ) ( 2 , y 2 ) (1,y_1)、(2,y_2) 均为 “不可走状态”,且 y 2 y 1 < = 1 |y_2-y_1|<=1 ,只要出现了这样的情况,那个人就无法到达终点了
  3. 利用3. 中分析到的,对于某个时刻我们只改变 某个方格 ( x , y ) (x,y) 的状态,那么我们要关心的就是与它挨着的三个方格的状态:(x ^ 1 , y-1 )、( x ^ 1、y)、(x ^ 1,y+1),如果(x,y)方格如果是从“可行走状态”变为了“不可行走状态”的话,我们考虑如果这个三个表格中(x ^ 1 , y-1 )、( x ^ 1、y)、(x ^ 1,y+1)只要存在“不可走状态”,这个时候(x,y)表格就可以与这三个为“不可走状态”的表格中建立“不可通行状态”,(实际上我们正要维护的就是不可通行的数量);反之如果(x,y)这个表格状态是从“不可通行”变为“可通行状态”的话,我们就要消除对应的不可通行状态,
  4. 如果某个时刻“不可通行的状态”的数量为0的话,这个时候是能到达终点的,输入yes

代码

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353
const int mxn = 2e5 + 10;
map<PIR, int> mp;
Pir pr;
int mz[3][mxn];

int main()
{
    /* fre(); */
    int n, q;
    scanf("%d %d", &n, &q);
    int sum = 0;
    while(q --)
    {
        scanf("%d %d", &pr.fi, &pr.se);
        mz[pr.fi][pr.se] = mz[pr.fi][pr.se] ^ 1;
        for(int j = pr.se - 1; j <= pr.se + 1; j ++)
        {
            int i = (pr.fi == 1 ? 2 : 1);
            if(i < 1 || j < 1 || i > 2 || j > n) continue;
            if(mz[pr.fi][pr.se])
            {
                if(mz[i][j])
                    sum ++;
            }
            else
            {
                if(mz[i][j])
                    sum --;
            }

        }

        if(sum)
            printf("No\n");
        else
            printf("Yes\n");
    }

    return 0;
}

D. Aroma’s Search(模拟?暴力?)

分析

  • 题意
  1. 这个一个二位坐标系内,给我们第一个金币的位置 ( x 0 , y 0 ) (x_0,y_0) ,之后又给我们了其它金币位置的地推表达式: ( a x x i 1 + b x ,     a y y i 1 + b y ) (a_x*x_{i-1}+b_x,~~~a_y*y_{i-1}+b_y) ,之后又给我我们玩家的初始位置 ( x s , y s ) (x_s,y_s) , 问玩家只能走t个单位距离的情况下最多能够获得多少个金币?
  • 思路
  1. 这一题的突破口就在数范围: 1 < = y 0 , y 0 < = 1 e 16      2 < = a x , a y < = 100    0 < = b x , b y < = 1 e 16 t < = 1 e 16 1<=y_0,y0<=1e16~~、~2<=a_x,a_y<=100~~、0<=b_x,b_y<=1e16、t<=1e16 ,虽然给的数据范围很大但是,由于金币的位置是递推出来的,所以在整个二位坐标系中再符合题意的情况下不会有多余63个金币出现,而且吃金币肯定是 吃一个连续的一段中的金币,所要我们暴力枚举所有 连续段 情况,找出其中最优答案即可。。。

  2. 这道题虽然按 2. 这一步中叙述的很简单,但是我们不免疑惑是否存在一种这样的情况:就是如果 玩家 先回去吃之前距离比较近的金币,最后如果吃完了之前比较近的金币之后,在回过头来吃后们的金币间隔比较的大,耗费的距离比较的大的金币呢??这种情况是存在的,不过我们比较 我们利用暴力枚举段的方法所走的最优路程a 与我们考虑折返情况的路程b 进行比较的话 发现 a路程 更短—>具体原因:通过对所走的路程构造“三角形两边之和一定大于第三边”,我们讲a与b路程重复的部分去掉发现,b路程剩下两条边与a路程只剩下一条边可以构成三角形,显然a路程剩下的那条边一定小鱼b路程剩下的两条边的距离之和,(可能这里没说清楚,但是主要的 考虑思路就在这里,自己多想想这点的证明),,,所以2.中叙述的方法是没问题的

代码

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353
const int mxn = 2e3 + 10;
const ull lim = 1e17; //主要这里必须是1e17,不能是1e16,自己想想吧
ll x[mxn], y[mxn];


int main()
{
    /* fre(); */
    ll ax, ay, bx, by; 
    scanf("%lld %lld %lld %lld %lld %lld", &x[0], &y[0], &ax, &ay, &bx, &by);
    ll sx, sy, t;
    scanf("%lld %lld %lld", &sx, &sy, &t);

    int n = 1;
    while(true)
    {
        x[n] = x[n - 1] * ax + bx;
        y[n] = y[n - 1] * ay + by;
        if(x[n] > lim || y[n] >  lim) break;
        n ++;
    }

    ll ans = 0;
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            ll t1 = abs(x[i] - sx) + abs(y[i] - sy);
            ll t2 = abs(x[j] - sx) + abs(y[j] - sy);
            ll t3 = min(t1, t2) + abs(x[i] - x[j]) + abs(y[i] - y[j]);
            if(t3 <= t)
                ans = max(ans, j - i + 1LL);
        }
    }
    printf("%lld\n", ans);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_34261446/article/details/106392421