Codeforces Round #394 div2

A. Dasha and Stairs(数学

http://codeforces.com/problemset/problem/761/A

题意:已知有a个偶数b个奇数,判断这些数能不能组成连续正整数数列。

算法:直接判断abs(a-b)≦1即可。注意a和b同时为0的情况。

代码:

#include<bits/stdc++.h>
#define REP(i, L, R) for(int i=L; i<=R; i++)
#define MST(A, x) memset(A, x, sizeof(A))
using namespace std;
typedef long long LL;
int main()
{
    int a, b;
    scanf("%d%d", &a, &b);
    if (a == 0 && b == 0) printf("NO");
    else
        if (abs(a-b) <= 1) printf("YES");
        else printf("NO");
    return 0;
}

B. Dasha and friends(枚举)

http://codeforces.com/problemset/problem/761/B

题意:已知一个长度为m的圆上有m个均匀的点,两个数列(到出发点的距离)分别描述两个走法,判断这两个走法能否重合。

算法:枚举两个走法的出发点,模拟判断即可。

代码:

#include<bits/stdc++.h>
#define REP(i, l, r) for(int i=l; i<=r; i++)
#define MST(A, x) memset(A, x, sizeof(A))
using namespace std;
typedef long long LL;
const int MAXN = 50+10;
const int MAXL = 100+10;
int n, L;
int a[MAXN], b[MAXN];
int main()
{
    scanf("%d %d", &n, &L);
    REP(i, 1, n) scanf("%d", &a[i]);
    REP(i, 1, n) scanf("%d", &b[i]);
    bool flag = false;
    REP(i, 0, L-1)
        REP(j, 0, L-1)
        {
            bool f[MAXL];
            MST(f, 0);
            REP(k, 1, n)
            {
                f[(i+a[k]) % L] = 1;
                f[(j+b[k]) % L] = 1;
            }
            int cnt = 0;
            REP(k, 0, L-1)
                if (f[k]) cnt++;
            if (cnt == n)
            {
                flag = true;
                break;
            }
        }
    if (flag) printf("YES");
    else printf("NO");
    return 0;
}

C. Dasha and Password(枚举)

http://codeforces.com/problemset/problem/761/C

题意:已知n个长度为m的字符串(看作环),每个字符串的首字符上有一个指针,可以通过一次操作使指针左移或右移一位,求最少多少次操作可使这n个指针指向的字符构成一个合法字符串(即存在特殊符号#*&其一、数字和小写字母)。

算法:枚举数字、字母和特殊符号分别取自哪一个字符串,计算需要操作次数并取最小值即可。

代码:

#include<bits/stdc++.h>
#define REP(i, l, r) for(int i=l; i<=r; i++)
#define MST(A, x) memset(A, x, sizeof(A))
using namespace std;
typedef long long LL;
const int MAXN = 50+10;
int n, m;
char str[MAXN][MAXN];
int pointer(int dlta)
{
    if (dlta < 0) return dlta+m;
    if (dlta >= m) return dlta-m;
    return dlta;
}
bool isDigit(char c)
{
    if (c>=‘0‘ && c<=‘9‘) return 1; else return 0;
}
bool isLetter(char c)
{
    if (c>=‘a‘ && c<=‘z‘) return 1; else return 0;
}
bool isSymbol(char c)
{
    if (c==‘#‘ || c==‘*‘ || c==‘&‘) return 1; else return 0;
}
int cal(int a, int b, int c)
{
    int ret = 0;
    bool flag = false;
    REP(d, 0, m-1)
        if (isDigit(str[a][pointer(d)]) || isDigit(str[a][pointer(-d)]))
        {ret += d;    flag = true;    break;}
    if (!flag) ret += m;

    flag = false;
    REP(d, 0, m-1)
        if (isLetter(str[b][pointer(d)]) || isLetter(str[b][pointer(-d)]))
        {ret += d;    flag = true;    break;}
    if (!flag) ret += m;

    flag = false;
    REP(d, 0, m-1)
        if (isSymbol(str[c][pointer(d)]) || isSymbol(str[c][pointer(-d)]))
        {ret += d;    flag = true;    break;}
    if (!flag) ret += m;

    return ret;
}
int main()
{
    scanf("%d %d", &n, &m);
    REP(i, 1, n) scanf("%s", str[i]);
    int res = 1<<25;
    REP(i, 1, n)
        REP(j, 1, n)
            REP(k, 1, n)
                if (i!=j && j!=k && k!=i) res = min(res, cal(i, j, k));
    printf("%d", res);
    return 0;
}

D. Dasha and Very Difficult Problem(贪心)

http://codeforces.com/problemset/problem/761/D

题意:已知三组数a,b,c满足且c中个元素互不相同,。给出数组a和数组p(描述数组c中个元素大小且),求任意一个可行的数组b;若无解则输出-1。

算法:我们有,可以求出的上界upper和下届lower。若upper-lower>r-l,则无解;否则根据lower和l的差调整即可。

代码:

#include<bits/stdc++.h>
#define REP(i, L, R) for(int i=L; i<=R; i++)
using namespace std;
const int MAXN = 1e5+10;
const int MAXX = 1e9+10;
int n, l, r;
int a[MAXN], b[MAXN], p[MAXN];
int main()
{
    scanf("%d %d %d", &n, &l, &r);
    REP(i, 1, n) scanf("%d", &a[i]);
    int lower = MAXX;
    int upper = 0;
    REP(i, 1, n)
    {
        scanf("%d", &p[i]);
        b[i] = a[i] + p[i];
        lower = min(lower, b[i]);
        upper = max(upper, b[i]);
    }
    if (upper-lower > r-l) printf("-1");
    else
    {
        int delta = l - lower;
        REP(i, 1, n)
        {
            b[i] += delta;
            printf("%d ", b[i]);
        }
    }
    return 0;
}

E. Dasha and Puzzle(DFS)

http://codeforces.com/problemset/problem/761/E

题意:已知一棵n个节点的树,判断能否将其放在笛卡尔坐标系中,使得每条边都平行于坐标轴且互不相交。

算法:首先,易知任意点的度数一定小于等于4,否则一定不能放在笛卡尔坐标系中。下面我们只需要从根节点开始深搜就可以了。因为题目要求可行解,我们将边长从2^58每次缩短一半即可。

代码:

#include<bits/stdc++.h>
#define REP(i, L, R) for(int i=L; i<=R; i++)
#define MST(A, x) memset(A, x, sizeof(A))
using namespace std;
typedef long long LL;
const int MAXN = 30+10;
const LL MAXX = 1e18+10;
const int DX[5] = {0, 1, -1, 0, 0};
const int DY[5] = {0, 0, 0, 1, -1};
int n;
int G[MAXN][MAXN];
int degree[MAXN], father[MAXN];
LL x[MAXN], y[MAXN];
int index(int k)
{
    if(k == 1) return 2;
    if(k == 2) return 1;
    if(k == 3) return 4;
    if(k == 4) return 3;
}
void DFS(int u, LL len, int k)
{
    REP(i, 1, degree[u])
        if(k && G[u][i]==father[u]) swap(G[u][i], G[u][index(k)]);
    REP(i, 1, degree[u])
    {
        int v = G[u][i];
        if (v == father[u]) continue;
        x[v] = x[u] + len*DX[i];
        y[v] = y[u] + len*DY[i];
        father[v] = u;
        DFS(v, len>>1, i);
    }
}
int main()
{
    scanf("%d", &n);
    bool over = false;
    REP(i, 1, n-1)
    {
        int u, v;
        scanf("%d %d", &u, &v);
        G[u][++degree[u]] = v;
        G[v][++degree[v]] = u;
        if (degree[u]>4 || degree[v]>4)
        {
            printf("NO");
            over = true;
            break;
        }
    }
    if (!over)
    {
        printf("YES\n");
        x[1] = y[1] = 0;
        father[1] = 1;
        DFS(1, 1LL<<58, 0);
        REP(i, 1, n) printf("%I64d %I64d\n", x[i], y[i]);
    }
    return 0;
}
时间: 2024-10-06 18:26:06

Codeforces Round #394 div2的相关文章

codeforces round #257 div2 C、D

本来应该认真做这场的,思路都是正确的. C题,是先该横切完或竖切完,无法满足刀数要求,再考虑横切+竖切(竖切+横切), 因为横切+竖切(或竖切+横切)会对切割的东西产生交叉份数,从而最小的部分不会尽可能的大. 代码如下,虽然比较长.比较乱,但完全可以压缩到几行,因为几乎是4小块重复的代码,自己也懒得压缩 注意一点,比如要判断最小块的时候,比如9行要分成2份,最小的剩下那份不是9取模2,而应该是4 m/(k+1)<=m-m/(k+1)*k          #include<bits/stdc+

codeforces Round #250 (div2)

a题,就不说了吧 b题,直接从大到小排序1-limit的所有数的lowbit,再从大到小贪心组成sum就行了 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #define N 200000 6 using namespace std; 7 int pos[N],a[N],s[N],f[N],la[N],b[N],i,j,k,ans,n,p

Codeforces Round#320 Div2 解题报告

Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Finding Team Member codeforces 579C A Problem about Polyline codeforces 579D "Or" Game codeforces 579E Weakness and Poorness codeforces 579F LCS Aga

Codeforces Round #254(div2)A

很有趣的题.想到了就非常简单,想不到就麻烦了. 其实就是一种逆向思维:最后结果肯定是这样子: WBWBWBWB... BWBWBWBW... WBWBWBWB... ... 里面有“-”的地方改成“-”就行了. 但是我开始是正着想的,想每个点怎么处理,这还要看它周围点的状态,越想越麻烦... 这题中体现的正难则反的逆向思维很值得学习. #include<iostream> #include<cstdio> #include<cstdlib> #include<cs

Codeforces Round #254(div2)B

就是看无向图有几个连通块,答案就是2n-num. 范围很小,就用矩阵来存图减少代码量. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm> #inc

Codeforces Round #260(div2)C(递推)

有明显的递推关系: f[i]表示i为数列中最大值时所求结果.num[i]表示数i在数列中出现了几次. 对于数i,要么删i,要么删i-1,只有这两种情况,且子问题还是一样的思路.那么很显然递推一下就行了:f[i]=max(f[i-1],f[i-2]+i*num[i]); 这里技巧在于:为了防止麻烦,干脆就所有数的出现次数都记录一下,然后直接从2推到100000(类似于下标排序),就不用排序了,也不用模拟删除操作了.这一技巧貌似简单,但实际上临场想出来也需要点水平. #include<iostrea

Codeforces Round #289 Div2 E

Problem 给一串长度为N的字符串,对于每个字符,若字符为元音,则权值为1,否则为0.一个子串的权值定义为该串所有字符权值之和除以字符个数,一个母串的权值定义为所有子串的权值之和.求母串的权值. Limits Time Limit(ms): 1000 Memory Limit(MB): 256 N: [1, 5*10^5] 字符集: 'A'-'Z' 元音: I E A O U Y Solution 考虑每个元音字符对母串的贡献,可以找出规律. More 举"ABCDOEFGHKMN"

Codeforces Round #403 div2 C. Andryusha and Colored Balloons

题目链接:Codeforces Round #403 div2 C. Andryusha and Colored Balloons 题意: 给你一棵n个节点的树,然后让你染色,规定相连的三个 节点不能同色,问需要的最少颜色,并输出其中一种方案. 题解: 因为只有相邻3个节点不同色. 所以直接DFS,每个节点都从1开始. 然后ans[v]!=ans[u]!=ans[fa]就行. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i&

CodeForces Round#229 DIV2 C 递推DP

对这道题目也只好说呵呵了,没注意k的范围最大才10,所以昨晚纠结了很久,没什么好的方法来处理,后来无奈想去翻翻题解,发现人家开头就来了句,因为k的范围比较小 所以.........我只好暂停马上回头看看题目,是的,k比较小所以完全可以先在询问前预处理DP一遍, DP就比较清晰了,dp[i][j]  (i>=0 && i<k,,,,j>=i && j <=n)代表意义呢 以i为开头的  区间[1,j]注意 是 1~j的 所需要的操作数,题目问的是最小操