前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Codeforces Round #674 (Div. 3)(A~D)

Codeforces Round #674 (Div. 3)(A~D)

作者头像
浪漫主义狗
发布2023-09-04 14:44:19
2340
发布2023-09-04 14:44:19
举报
文章被收录于专栏:HAUE_LYS'Blog

本文最后更新于 326 天前,其中的信息可能已经有所发展或是发生改变。

A. Floor Number


Origional Link

题目大意

  • 给定目标房间编号 n 及一层楼住户数量 x
  • 第一层楼只有 2 个住户,求目标房间所在楼层。

思想

  • 签到题。
  • n\le2 时在第一层。
  • n\gt 2 时: 若 x 可以整除 n-2,则在 \frac{n-2}{m} + 1 层; 反之在 \frac{n-2}{m} + 2 层。

代码

代码语言:javascript
复制
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
#define re register
#define fi first
#define se second
#define endl '\n'

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const int N = 1e6 + 3;
const int INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-6, PI = acos(-1);

int a[N];

void solve(){

    int n, x;

    cin >> n >> x;

    if(n <= 2) cout << 1 << endl;
    else{
        int t = (n - 2) / x + 1;
        if((n - 2) % x != 0) t ++;
        cout << t << endl;
    }

}

int main(){

    IOS;

    int _ = 1;

    cin >> _;

    while(_ --){
        solve();
    }

    return 0;

}

B. Symmetric Matrix


Origional Link

题目大意

  • 给定 n2\times 2 的矩阵,每个矩阵有无限多个。
  • 求这些矩阵是否可以组合成一个 m\times m 的大矩阵,且使得大矩阵的元素关于主对角线对称。

思想

  • 思维题。
  • 可以构成的大前提条件是 2 可以整除 m
  • 其次使得大矩阵的元素关于主对角线对称,只需要每个小矩阵的元素次对角线上的元素相同即可。

代码

代码语言:javascript
复制
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
#define re register
#define fi first
#define se second
#define endl '\n'

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const int N = 1e6 + 3;
const int INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-6, PI = acos(-1);

void solve(){

    int n, m; cin >> n >> m;

    bool flag = 0;

    for(int i = 0; i < n; i ++){
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        if(b == c) flag = 1;
    }

    if(flag && m % 2 == 0) cout << "YES" << endl;
    else cout << "NO" << endl;

}

int main(){

    IOS;

    int _ = 1;

    cin >> _;

    while(_ --){
        solve();
    }

    return 0;

}

C. Increase and Copy


Origional Link

题目大意

  • 给定一个序列 a = [1]
  • 不限次数进行如下操作: 选择 a_i 使其变为 a_i+1; 选择 a_i 将其复制并加入到 a 的末尾。
  • 给定一个整数 n,求最少经过多少次操作可以使得 a 的元素之和至少是 n

思想

  • 思维题。
  • 最快的方法是将 a_i 不断变为 a_i + 1,之后不断执行复制操作,直到总和 sum \ge n
  • 我们设 a_i 通过 i+1 操作最后得到的数为 x,复制 xj 次后得到大于等于 n 的数,即: x \times (j+1) \ge n
  • i+j 的最小值等价于先求 x + (j+1) 的最小值,显然地,当 xj + 1 尽可能接近 \sqrt{n} 时可以使得 x+(j+1) 最小。
  • 综上所述,我们需要找到尽可能接近 \sqrt{n} 的最大整数。

代码

代码语言:javascript
复制
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
#define re register
#define fi first
#define se second
#define endl '\n'

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const int N = 1e6 + 3;
const int INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-6, PI = acos(-1);

void solve(){

    int n; cin >> n;
    int t = sqrt(n);
    if(t * t == n) cout << 2 * (t - 1) << endl;
    else if(t * (t + 1) >= n) cout << 2 * t - 1 << endl;
    else cout << 2 * t  << endl;

}

int main(){

    IOS;

    int _ = 1;

    cin >> _;

    while(_ --){
        solve();
    }

    return 0;

}

D. Non-zero Segments


Origional Link

题目大意

  • 给定一个序列 a,可以在任意相邻对中添加任意大小的数,最终使得不存在一个子序列的和为 0
  • 求最少的添加次数。

思想;

  • 前缀和,贪心。
  • 破坏所有连续的区间和为 0 的区间,可以使用前缀和预处理区间和。
  • 当区间 [l,r] 和为 0 时,有 a[l - 1] = a[r]。
  • 从左往右扫描每个区间的左端点,用 map<LL, int> st 存储出现过的前缀。
  • 那么当出现相同的前缀和,说明存在和为 0 的子序列,此时需要在其区间加上一个数。
  • 保证在此之前的所有子序列没有存在和为 0 的前缀,则当前位置改变,其左边区间可以不再考虑,记录操作并且清空 st。
  • 注意,由于子区间有可能在端点处重合,这种情况不属于有重复部分,所以清空 st 以后还需要插入当前位置左侧一位置的前缀和。

代码

代码语言:javascript
复制
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
#define re register
#define fi first
#define se second
#define endl '\n'

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const int N = 1e6 + 3;
const int INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-6, PI = acos(-1);

LL a[N];

void solve(){

    map<LL, int> st; 

    int n; cin >> n;
    for(int i = 1; i <= n; i ++){
        cin >> a[i];
        a[i] += a[i - 1];
    }

    LL cnt = 0;

    for(int i = 1; i <= n; i ++){
        if(st[a[i]] > 0){
            cnt ++;
            st.clear();
        }
        st[a[i - 1]] ++;
    }

    cout << cnt << endl;

}

int main(){

    IOS;

    int _ = 1;

    // cin >> _;

    while(_ --){
        solve();
    }

    return 0;

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • A. Floor Number
  • B. Symmetric Matrix
  • C. Increase and Copy
  • D. Non-zero Segments
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档