Codeforces Round #605 (Div. 3)

地址:http://codeforces.com/contest/1272

A. Three Friends

仔细读题能够发现|a-b| + |a-c| + |b-c| = |R-L|*2 (其中L = min{a, b, c}, R = max{a, b, c})

那么本题的移动条件就只考虑两个端点L, R即可,答案即为 |(L+1)-(R-1)| 即L向右移动1,R向左移动1,在此之前判断一下原L,R之间的距离是否<=2,<=2输出0

#include <bits/stdc++.h>
using namespace std;

int q, a[3];
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> q;
    while( q-- ){
        for( int i=0; i<3; i++ ) cin >> a[i];
        sort(a, a+3);
        if( a[2]-a[0]<=2 ) cout << "0" << endl;
        else cout << (a[2]-a[0]-2)*2 << endl;
    }

    return 0;
}

A.Three Friends

B.Snow Walking Robot

这题比赛时没做出来??理解题意出了锅。

思路:如果能够回到(0, 0)需满足数量U=D且R=L,只需要上下方向选min(U, D),左右方向选min(L, R)。

如果U=0或D=0那么就要删除所有的另外一个方向,且将左右方向置为1(min(L, R)>0),对于R和L也一样要满足该条件,上下方向置为1(min(U, D)>0)

然后最后组合的时候只需要让路径构成一个环即可,这个组合可以任意组合,做题的时候卡在这了。。。

#include <bits/stdc++.h>
using namespace std;

int q, cl, cr, cu, cd;
string s;
int main(){
    // freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> q;
    while( q-- ){
        cin >> s;
        cl = cr = cu = cd = 0;
        for( char i:s ){
            cl += i==‘L‘;
            cr += i==‘R‘;
            cu += i==‘U‘;
            cd += i==‘D‘;
        }
        cu = min(cu, cd);
        cl = min(cl, cr);
        if( cu==0 || cl==0 ){
            cl = min(1, cl);
            cu = min(1, cu);
        }
        string ans;
        for( int i=0; i<cl; i++ ) ans += ‘R‘;
        for( int i=0; i<cu; i++ ) ans += ‘U‘;
        for( int i=0; i<cl; i++ ) ans += ‘L‘;
        for( int i=0; i<cu; i++ ) ans += ‘D‘;
        cout << ans.size() << endl << ans << endl;
    }

    return 0;
}

B.Snow Walking Robot

C.Yet Another Broken Keyboard

给k个字母问这k的字母能构成字符串s中多少个子串。

set存一下这k个字母,对s中每一段连续的可以在set中查找到的分别进行统计汇总即可,每一段长度len_i对答案的贡献为(len_i)*(len_i+1)/2.

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
int n, k;
string s;
set<char> a;
ll ans, tmp;
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n >> k >> s;
    for( int i=0; i<k; i++ ){
        char ch;
        cin >> ch;
        a.insert(ch);
    }
    int len = s.size();
    for( int i=0; i<len; i++ ){
        if( a.find(s[i])!=a.end() )
            tmp ++;
        else{
            ans += tmp*(tmp+1)/2;
            tmp = 0;
        }
    }
    if(tmp) ans += tmp*(tmp+1)/2;
    cout << ans << endl;

    return 0;
}

C.Yet Another Broken Keyboard

D. Remove One Element

三遍预处理 + 一遍原序列

第一遍预处理处理出来一个数不删的最大长度。

第二遍预处理从i from 1~n记录l[i]从左到右递增的最长连续序列长度。

第三遍预处理从i from n~1记录r[i]从右到左递减的最长连续序列长度。

最后跑原序列i from 1~n判断删除i之后的结果能否更新第一遍记录的答案

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 5;
int a[maxn], n, l[maxn], r[maxn], ans;
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n;
    for( int i=0; i<n; i++ ) cin >> a[i];
    int tmp = 1;
    for( int i=1; i<n; i++ ){
        if( a[i]>a[i-1] ) tmp++;
        else tmp = 1;
        ans = max(ans, tmp);
    }
    l[0] = 1;
    for( int i=1; i<n; i++ ){
        if( a[i]>a[i-1] ) l[i] = l[i-1]+1;
        else l[i] = 1;
    }
    r[n-1] = 1;
    for( int i=n-2; ~i; i-- ){
        if( a[i]<a[i+1] ) r[i] = r[i+1]+1;
        else r[i] = 1;
    }
    for( int i=1; i<n-1; i++ )
        if( a[i-1]<a[i+1] ) ans = max(ans, l[i-1]+r[i+1]);
    cout << ans << endl;

    return 0;
}

D. Remove One Element

E.Nearest Opposite Parity

比赛时dfs写MLE,时间不够放弃。

预处理 + bfs通过,使用bfs理由->最短路

预处理出来答案为1的点,然后放进队列,同时将所有点i from 1~n可以跳到的位置i-a[i]和i+a[i]连边然后bfs

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
int n, a[maxn], ans[maxn];
vector<int> p[maxn];
int main(){
    memset( ans, -1, sizeof(ans) );
    scanf("%d", &n);
    for( int i=0; i<n; i++ ) scanf("%d", &a[i]);
    queue<int> q;
    for( int i=0; i<n; i++ ){
        if( i-a[i]>=0 ){
            p[i-a[i]].push_back(i);
            if( a[i-a[i]]%2 != a[i]%2 ) ans[i] = 1;
        }
        if( i+a[i]<n ){
            p[i+a[i]].push_back(i);
            if( a[i+a[i]]%2 != a[i]%2 ) ans[i] = 1;
        }
        if( ans[i]==1 ) q.push(i);
    }
    while( q.size() ){
        int x = q.front();
        q.pop();
        for( auto i:p[x] ){
            if( ans[i]==-1 && a[i]%2==a[x]%2 ){
                ans[i] = ans[x]+1;
                q.push(i);
            }
        }
    }
    for( int i=0; i<n; i++ ){
        printf("%d", ans[i]);
        if( i==n-1 ) puts("");
        else putchar(‘ ‘);
    }

    return 0;
}

E.Nearest Opposite Parity

原文地址:https://www.cnblogs.com/WAautomaton/p/12037249.html

时间: 2024-11-08 11:22:31

Codeforces Round #605 (Div. 3)的相关文章

Codeforces Round #605 (Div. 3) E - Nearest Opposite Parity

题目链接:http://codeforces.com/contest/1272/problem/E 题意:给定n,给定n个数a[i],对每个数输出d[i]. 对于每个i,可以移动到i+a[i]和i-a[i](如果i+a[i]<=n,i-a[i]>=1) d[i]是指从i移动到任意一个j的步数,需满足条件a[i]和a[j]的奇偶性不同 不论奇偶,相连的边先放进vector邻接表中 如果i和i+a[i]奇偶性不同,那么ans[i]为1,把i放到queue队列里 同理,如果i和i-a[i]奇偶性不同

Codeforces Round #605 (Div. 3) E - Nearest Opposite Parity (超级源点)

?? ?? ?? 题意:一个数组,i位置可以到达i +/- a[ i ] 位置(不越界情况下),问你每个位置要走到一个奇偶性相反的地点最少要走几次, 在现场,,然而我真的不会哈哈哈哈我好菜?? 主要是两点:超级源点(多源变单源)+ 反向建边(反向思维) 建立一个超级奇数点,一个超级偶数点: 超级奇数点为例,从该点出发,配合我们建立的反向边, 如果可以到达某个偶数点,求得的距离肯定是所有能到达他的奇数点中最小的(最短路中任意一条子路最短) 还有就是图里面写搜索记得开vis,,,树里面搜索可以不写,

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除

Codeforces Round #339 (Div. 2) B. Gena&#39;s Code

B. Gena's Code It's the year 4527 and the tanks game that we all know and love still exists. There also exists Great Gena's code, written in 2016. The problem this code solves is: given the number of tanks that go into the battle from each country, f

Codeforces Round #315 (Div. 1)

A. Primes or Palindromes? time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Rikhail Mubinchik believes that the current definition of prime numbers is obsolete as they are too complex and un