Codeforces Round #515 (Div. 3)

记一次灰常失败的打cf经历,暴露了自己的许多问题,以及自己逻辑能力和代码能力不是很强

A题:http://codeforces.com/contest/1066/problem/A
这道水题上来,想暴力遍历,不可能,但是那个(L,R],处理的不好,这个逻辑没搞好,导致12分才a。。。。其实左开就是为了取上界,(R / v ) - (L + v - 1) / v + 1;

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 1e5 + 5;

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        LL L,v,l,r;
        cin >> L >> v >> l >> r;
        LL k = L / v;
        LL p = (r / v) - ((l + v - 1) / v) + 1;
        //cout << k << " " << p << endl;
        cout << k - p << endl;
    }
    return 0;
}

B题:http://codeforces.com/contest/1066/problem/B
其实这道题思路很清晰,但是我就是对这种类似两点移动的这种代码就很烦,那个地方没写好就是一堆bug或者是wa,以后要多做这种题的训练,不能嫌烦,敲定做法后先构造一遍代码思路再敲,要不然会敲很长时间,右边界没处理好,一直wa。。。。大的教训啊,希望自己以后逻辑思维能强点
代码写的比较丑,其实先判定是否输出-1,直接暴力vis标记就行,但是当时思维就是不对劲。。。
还想边滑动会判断-1的情况,写了两个版本,都删掉了,特别困难。。。还是先把-1的情况过滤掉吧
右边界的话,如果出现某个点的右边界大于n,那么就可以输出了,否则可能会多判

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 1005;

int a[N][2];

int main()
{
    int n,r;
    int k = 0;
    scanf("%d %d",&n,&r);
    for(int i = 1;i <= n;++i){
        int x;
        scanf("%d",&x);
        if(x == 1){
            a[k][0] = i - r + 1;
            a[k++][1] = i + r - 1;
        }
    }
    for(int i = 0;i < k;++i){
        if(i == 0){
            if(a[i][0] > 1){
                printf("-1\n");
                return 0;
            }
        }else{
            if(a[i][0] - a[i - 1][1] > 1){
                printf("-1\n");
                return 0;
            }
        }
    }
    if(a[k - 1][1] < n){
        printf("-1\n");
        return 0;
    }
    int p = 1;
    int pre = 1;
    int cnt = 0;
    for(int i = 0;i < k;++i){
        if(a[i][0] <= p){
            pre = a[i][1] + 1;
        }else{
            cnt++;
            p = pre;
            if(p > n){
                printf("%d\n",cnt);
                return 0;
            }
            i--;
        }
    }
    if(pre > n){
        cnt++;
        printf("%d\n",cnt);
    }
    return 0;
}

C题:http://codeforces.com/contest/1066/problem/C

赛后补的题,这道题直接上来用双端队列,查询用find函数,必定超时。。。。。
然后怎么办呢,其实两点法(为什么想不到呢),设一个左边界,一个右边界,查询应该是O(1)查询,所以需要一个pos数组存一下它的放的位置。。。。把起始位置设为300000。。。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 3 * 1e5;

int pos[200005];

int main()
{
    int q;
    scanf("%d",&q);
    char ch;int x;
    int l = 300000,r = 300000;
    scanf(" %c %d",&ch,&x);
    pos[x] = l;
    for(int i = 1;i < q;++i){
        scanf(" %c %d",&ch,&x);
        if(ch == 'L'){
            l--;pos[x] = l;
        }else if(ch == 'R'){
            r++,pos[x] = r;
        }else{
            int tmp = pos[x];
            printf("%d\n",min(tmp - l,r - tmp));
        }
    }
    return 0;
}


D题:http://codeforces.com/contest/1066/problem/D

我觉得这道题的最大值有点迷惑人,弄的题意和自己理解的有点偏差,按他给的程序那样走的话,因为物品必须都遍历完,所以直接倒着装物品,因为最后的物品是一定被装在盒子里的

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double PI = acos(-1);
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 2 * 1e5 + 5;

int a[N];

int main()
{
    int n,m,k;
    scanf("%d %d %d",&n,&m,&k);
    for(int i = 1;i <= n;++i){
        scanf("%d",&a[i]);
    }
    int cnt = n;
    while(m--)
    {
        int sum = 0;
        while(cnt >= 1 && sum + a[cnt] <= k){
            sum += a[cnt--];
        }
    }
    printf("%d\n",n - cnt);
    return 0;
}

E题:http://codeforces.com/contest/1066/problem/E

这道题显然比前面三题简单点,赛后也是马上就有想法,马上打出来的

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 2 * 1e5 + 5;
const LL mod = 998244353;

char s1[N];
char s2[N];
LL b[N];

LL pow_mod(LL n,LL m)
{
    LL x = n;
    LL sum = 1;
    while(m){
        if(m & 1) sum = sum * x % mod;
        m >>= 1;
        x = x * x % mod;
    }
    return sum;
}

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    scanf("%s",s1);
    scanf("%s",s2);
    for(int i = 0;i < m;++i){
        b[i] = s2[i] - '0';
    }
    for(int i = 1;i < m;++i){
        b[i] += b[i - 1];
    }
    int k = m - 1;
    int MIN = min(n,m);
    int len = n;
    LL sum = 0;
    for(int i = len - 1;i >= len - MIN;--i,--k){
        if(s1[i] == '1'){
            sum = (sum + b[k] * pow_mod(2LL,len - 1 - i) % mod) % mod;
            //cout << sum  << endl;
        }
        //cout << pow_mod(2LL,len - 1 - i) << endl;
    }
    printf("%lld\n",sum);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/83040708