Codeforces Round #534 (Div. 1)

A

构造题
有一个44的方格 每次放入一个横向12或竖向2*1的方格
满了一行或一列就会消掉
求方案

不放最后一行 这样竖行就不会消
然后竖着的放前两行 横着的放第三行 循环放就可以啦

#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
const int N = 1e3 + 5;
using namespace std;
const int r[2][2] = {{3, 1}, {3, 3}};
const int c[4][2] = {{1, 1}, {1, 2}, {1, 3}, {1, 4}};
char str[N];
int main(){
    scanf("%s", str + 1);
    int len = strlen(str + 1);
    int cntr = 0, cntc = 0;
    for(int i = 1; i <= len; ++i){
        if(str[i] == '1'){
            printf("%d %d\n", r[cntr][0], r[cntr][1]);
            ++cntr; if(cntr >= 2) cntr -= 2;
        }
        else {
            printf("%d %d\n", c[cntc][0], c[cntc][1]);
            ++cntc; if(cntc >= 4) cntc -= 4;
        }
    }
    return 0;
}

B

这是一道交互题
有一个数a 现在你每次可以询问"? x y"
如果\(x \mod a >= y \mod a\) 那么返回"x" 否则返回"y"
如果得出结果 就输出"! a" a是猜到的值
多数据 每轮以start开头 end表示结束
每轮询问不能超过60次
\(a \leq 1e9\)

首先考虑特判1
用"? 0 1"就可以 (x表示是1)
现在已经知道不是1了 就用"? 1 2"来判
显然如果a == 2那么返回x
如果a >= 3那么返回y
依此类推 倍增就好啦 注意每次询问是左开右闭的
扩大到\(x \le a \leq y\)时 用同样的方法每次收拢\(frac{y - x}{2}\)个就好啦
直到y - x == 1此时y就是答案
1e9 < 2 ^ 30
再加上第一次特判 显然可过

C

给你一张没有重边自环的n个点m条边的无向图 还有一个常数k
保证每个点度数至少为3
要求完成下列任务之一即可 如果都无解输出-1
任务一:找到一条长度至少为\(\lfloor frac{n}{k} \rfloor\)的路径
任务二:找到k个环 每个环要求满足:

  • 1 长度至少为3
  • 2 长度不是3的倍数
  • 3 这个环里必须至少有一个点满足它只属于这个环 不属于其他环
    \(n, k \leq 2.5 * 10^5 m \leq 5 * 10^5\)
    HINT 标签:constructive algorithms, dfs and similar

首先任务一很好办啊 bfs一下纪录father就可以了
如果没有的话 任务二中显然如果有两个环有公共边 那么这两个环上的点都不能做representative - vertex
先把这张图tarjan一波
对于一个双连通分量 如果其中不是割点的点度数有大于2的 那么说明有多环
所以我们在找到一个强连通分量的时候
如果这个bc里面(所有点都是割点并且这些割点都不是单独的) 或者有不是割点的点度数大于2 那么弃掉它
否则这整个就是一个环(或者单点) 判断它是不是\(size \geq 3\)
如果是就可以输出

orz

#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
const int N = 5e5 + 5;
using namespace std;
struct Edge{
    int v, next;
}edge[N << 1];
int head[N], esize;
inline void addedge(int x, int y){
    edge[++esize] = (Edge){y, head[x]}; head[x] = esize;
}
int n, m, k;
int dfn[N], tim, dis[N], fa[N], mx;
vector<int> cyc, leaf, son;
bool vis[N];
void dfs(int x, int ff){
    dfn[x] = ++tim, dis[x] = dis[ff] + 1, fa[x] = ff;
    if(dis[mx] < dis[x]) mx = x;
    vis[x] = 1;
    bool lf = 1;
    for(int i = head[x], vv; ~i; i = edge[i].next){
        vv = edge[i].v; if(vis[vv]) continue;
        dfs(vv, x);
        lf = 0;
    }
    if(lf) leaf.push_back(x);
}

int main(){
    memset(head, -1, sizeof(head));
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1, x, y; i <= m; ++i){
        scanf("%d%d", &x, &y);
        addedge(x, y), addedge(y, x);
    }
    dfs(1, 0);
    if(dis[mx] > (n / k)){
        printf("PATH\n%d\n", dis[mx]);
        while(mx)
            printf("%d ", mx), mx = fa[mx];
    }
    else {
        printf("CYCLES\n");
        int cnt = 0;
        for(auto i : leaf){
            son.clear(); cyc.clear();
            for(int j = head[i]; ~j; j = edge[j].next) if(edge[j].v != fa[i]) son.push_back(edge[j].v);

            if((dis[i] - dis[son[0]]) % 3 != 2){
            //printf("%d %d\n", dis[i], dis[son[0]]);
                int j = i;
                while(j != son[0]) cyc.push_back(j), j = fa[j];
                cyc.push_back(j);
            }
            else if((dis[i] - dis[son[1]]) % 3 != 2){
                int j = i;
                while(j != son[1]) cyc.push_back(j), j = fa[j];
                cyc.push_back(j);
            }
            else {
                //printf("*");
                if(dis[son[0]] < dis[son[1]]) swap(son[0], son[1]);
                cyc.push_back(i);
                int j = son[0];
                while(j != son[1]) cyc.push_back(j), j = fa[j];
                cyc.push_back(j);
            }
            printf("%d\n", cyc.size());
            for(auto j : cyc) printf("%d ", j);
            printf("\n");
            if(++cnt == k) break;
        }
    }
    return 0;
}

D

原文地址:https://www.cnblogs.com/hjmmm/p/10775193.html

时间: 2024-08-30 06:15:29

Codeforces Round #534 (Div. 1)的相关文章

Codeforces Round #534 (Div. 2)题解

Codeforces Round #534 (Div. 2)题解 A. Splitting into digits 题目大意 将一个数字分成几部分,几部分求和既是原数,问如何分可以使得分出来的各个数之间的差值尽可能小 解题思路 将n分成n个1相加即可 AC代码 #include<cstring> #include<string> #include<iostream> #include<cstdio> using namespace std; int main

Codeforces Round #534 (Div. 2) D. Game with modulo(取余性质+二分)

D. Game with modulo 题目链接:https://codeforces.com/contest/1104/problem/D 题意: 这题是一个交互题,首先一开始会有一个数a,你最终的目的是要将它猜出来. 每次询问会输出"? x y",然后有: "x" (without quotes), if (x % a)≥(y % a). "y" (without quotes), if (x % a)<(y % a). 最多给你60次

CF1103C Johnny Solving (Codeforces Round #534 (Div. 1)) 思维+构造

题目传送门 https://codeforces.com/contest/1103/problem/C 题解 这个题还算一个有难度的不错的题目吧. 题目给出了两种回答方式: 找出一条长度 \(\geq \frac nk\) 的路径: 找出 \(k\) 个简单环,满足长度不是 \(3\) 的倍数,并且每个环至少存在一个点不在别的环中. 很显然题目并不是要你随便挑一种回答方式开始单独研究.最有可能的情况是两种回答方式可以替补. 如果我们随便作出原图的一棵生成树,如果最长的路径长度 \(\geq \f

Codeforces Round #534 (Div. 2) Solution

A. Splitting into digits Solved. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int n; 5 6 void solve() 7 { 8 printf("%d\n", n); 9 for (int i = 1; i <= n; ++i) printf("%d%c", 1, " \n"[i == n]); 10 } 11 12 int

Codeforces Round #534 (Div. 2)

A. Splitting into digits 题意:把一个数分成若干[1,9]之间的数字,使得这些数尽量相同. 思路:输出n个1. #include<bits/stdc++.h> #define CLR(a,b) memset(a,,sizeof(a)) using namespace std; typedef long long ll; const int maxn=100010; int main(){ int n; cin>>n; int flag=0,j=2; prin

[ACM]Codeforces Round #534 (Div. 2)

一.前言 二.题面 A. Splitting into digits Vasya has his favourite number n. He wants to split it to some non-zero digits. It means, that he wants to choose some digits d1,d2,-,dk, such that 1≤di≤9 for all i and d1+d2+-+dk=n. Vasya likes beauty in everything

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序列,如果我