Codeforces Round #547 (Div. 3)

题目链接:https://codeforces.com/contest/1141

A,B咕咕了...

C. Polycarp Restores Permutation

题意:

有一个n的排列,但现在只给出相邻两位的差,问原排列是多少,如果不存在就输出-1。

题解:

通过相邻两位的差我们可以知道第一个元素和其它位置元素的大小关系,然后根据这个来搞一波就行了。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + ;
int n;
int a[N], b[N], c[N];
int main() {
ios::sync_with_stdio(false);
cin.tie();
cin >> n;
for(int i = ; i < n; i++)
cin >> a[i];
b[] = ;
for(int i = ; i < n; i++) {
b[i + ] = b[i] + a[i];
}
int mn = *min_element(b + , b + n + );
for(int i = ; i <= n; i++)
b[i] += - mn;
for(int i = ; i <= n; i++)
c[i] = b[i];
sort(c + , c + n + );
int check = ;
for(int i = ; i <= n; i++) {
if(c[i] != i)
check = ;
}
if(check) {
cout << -;
} else {
for(int i = ; i <= n; i++)
cout << b[i] << " ";
}
return ;
}

D. Colored Boots

题意:

给出两个字符串,然后问这两个字符串中字符的最大匹配是多少,并且输出相应的匹配。两个字符串中的字符可以匹配,要么两个字符相等,要么其中一个是"?"。

题解:

这个题我的做法就是对第二个字符串中的字符插入一个pair型的set里面,然后通过二分来搞,当然还有一点暴力。反正就是分几种情况匹配就是了。

但其实可以直接将所有种类的字符作为链表头,然后每次插入其对应的位置,最后一次来匹配就行了,具体实现方法就是利用队列或者vector。

给出我的代码吧...

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = ;
int n;
char s[N], t[N];
int vis[N];
set <pair<char, int > > S;
vector <pair<int, int> >g;
int main() {
cin >> n;
scanf("%s%s", s + , t + );
for(int i = ; i <= n; i++) {
S.insert(mp(t[i], i));
}
int ans = ;
for(int i = ; i <= n; i++) {
char c = s[i];
if(c != '?') {
auto it = S.lower_bound({c, -});
if(it == S.end())
continue ;
if(it->first == c) {
ans++;
g.push_back(mp(i, it->second));
S.erase(it);
vis[i] = ;
}
}
}
int i = ;
while(!S.empty()) {
auto it = S.begin();
char c = it->first;
int id = it->second;
if(c != '?')
break ;
for(; i <= n; i++) {
if(vis[i] || s[i] == '?')
continue ;
ans++;
g.push_back(mp(i, id));
S.erase(it);
i++;
break ;
}
if(i == n + )
break ;
}
i = ;
while(!S.empty()) {
for(; i <= n; i++) {
if(!vis[i] && s[i] == '?') {
ans++;
auto it = S.begin();
g.push_back(mp(i, it->second));
vis[i] = ;
S.erase(it);
i++;
break ;
}
}
if(i == n + )
break ;
}
printf("%d\n", ans);
for(auto v : g) {
printf("%d %d\n", v.first, v.second);
}
return ;
}

E. Superhero Battle

题意:

给出怪兽的初始血量,然后有无穷多个回合,每个回合怪兽都会损失或者增加一些血量,但是这些回合是有循环节的,现在给出循环节的具体信息。

问最后怪兽的血量是否能够小于等于0,如果可以,就输出怪兽最早是在哪一个回合阵亡的。

题解:

首先预处理出一个前缀和,然后特别判断一下第一轮的情况以及不会阵亡的情况。

然后我的做法就是枚举一下这个怪兽在1~n-1哪个位置会阵亡,然后通过这个算回合数,最终维护一下答案就行了。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+;
int n;
ll a[N],sum[N];
ll h;
int main(){
ios::sync_with_stdio(false);cin.tie();
cin>>h>>n;
for(int i=;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-]+a[i];
}
for(int i=;i<=n;i++){
if(h+sum[i]<=){
cout<<i;
return ;
}
}
if(sum[n]>=){
cout<<-;
return ;
}
//
ll tmp = h;
ll ans = 1e18;
for(ll i=;i<=n;i++){
tmp = h ;
tmp+=sum[i];
ll now = abs(sum[n]);
ll cnt = (tmp-)/now+;
ans=min(ans,cnt*n+i);
}
cout<<ans;
return ;
}

F2. Same Sum Blocks (Hard)

题意:

给出n个数,然后求数量最多的,并且区间和相等,不交叉的区间,最后将区间信息输出出来。

题解:

由于n的范围不是很大,所以我们可以采用稍暴力一点的做法,直接将所有区间的信息:包括左右端点、区间和存起来,用一个pair保存左右端点,然后放入一个一维为sum的vector里面,然后暴力来求就是了。当然由于区间和可能比较大,所以可以离散化一波,或者用map来保存。

之后就是对于每一个和,找到他所有的区间,来更新答案就是了。这里有一个技巧,如果我们是按照左端点来排序的话,贪心起来有点困难;贪心的最优选择还是按照右端点来排序,所以一开始我们存进pair里面的时候,把左右端点对调一下,这样后面sort的时候就是优先对右端点进行排序了。

代码如下:

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = ;
int n;
int a[N], sum[N], b[N*N];
vector <pii> g[N * N], T, res;
int main() {
ios::sync_with_stdio(false);
cin.tie();
cin >> n;
for(int i = ; i <= n; i++) {
cin >> a[i];
sum[i] = sum[i - ] + a[i];
}
int D = ;
for(int i = ; i <= n; i++) {
for(int j = ; j <= i; j++) {
b[++D] = sum[i] - sum[j - ];
}
}
sort(b + , b + D + );
D = unique(b + , b + D + ) - b;
for(int i = ; i <= n; i++) {
for(int j = ; j <= i; j++) {
int p = lower_bound(b + , b + D + , sum[i] - sum[j - ]) - b;
g[p].emplace_back(mp(i, j));
}
}
int l, ans = , p;
for(int i = ; i < N * N; i++) {
if((int)g[i].size() != ) {
l = ;
T.clear();
sort(g[i].begin(), g[i].end());
int pre = -;
for(int j = ; j < g[i].size(); j++) {
if(g[i][j].second > pre) {
T.emplace_back(g[i][j]);
pre = g[i][j].first;
}
}
if((int)T.size() > (int)res.size()) {
swap(T, res);
}
}
}
cout << (int)res.size() << '\n';;
for(int i = ; i < res.size(); i++) {
cout << res[i].second << " " << res[i].first << '\n';
}
return ;
}

G. Privatization of Roads in Treeland

题意:

给一颗树染色,然后问最少需要几种颜色。若与一个点相接的几条边有重复的颜色,那么这个点被叫做“怒气”点。题目中会给出k这个限制条件,意即“怒气”点不超过k个。

题解:

二分有多少个“怒气”点,或者也直接贪心地取k个怒气点就行,这k个怒气点都是度数最大的那几个点。

然后dfs染色一下就行了,顺便记录一下答案。因为此时是保证有解的。

代码如下:

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 2e5+;
int n,k;
vector <pair<int,int> > g[N];
int du[N];
int ans[N];
int l,r,mid;
bool check(int x){
int cnt = ;
for(int i=;i<=n;i++){
if(du[i]>x) cnt++;
}
return cnt<=k;
}
void dfs(int u,int fa,int cnt){
for(auto to:g[u]){
int v = to.first,id = to.second;
if(v==fa) continue ;
ans[id]=cnt++;;
if(cnt>r) cnt = ;
dfs(v,u,cnt);
}
}
int main(){
ios::sync_with_stdio(false);cin.tie();
cin>>n>>k;
for(int i=;i<n;i++){
int u,v;
cin>>u>>v;
g[u].push_back(mp(v,i));
g[v].push_back(mp(u,i));
du[u]++;du[v]++;
}
l=,r=N;
while(l<r){
mid = (l+r)>>;
if(check(mid)) r=mid;
else l=mid+;
}
cout<<r<<'\n';
dfs(,-,);
for(int i=;i<n;i++) cout<<ans[i]<<" ";
return ;
}

Codeforces Round #547 (Div. 3) 题解的更多相关文章

  1. Codeforces Round #182 (Div. 1)题解【ABCD】

    Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...

  2. Codeforces Round #608 (Div. 2) 题解

    目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...

  3. Codeforces Round #525 (Div. 2)题解

    Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...

  4. Codeforces Round #528 (Div. 2)题解

    Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...

  5. Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F

    Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...

  6. Codeforces Round #677 (Div. 3) 题解

    Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...

  7. Codeforces Round #665 (Div. 2) 题解

    Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...

  8. Codeforces Round #160 (Div. 1) 题解【ABCD】

    Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...

  9. Codeforces Round #383 (Div. 2) 题解【ABCDE】

    Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...

随机推荐

  1. 交换学生 (Foreign Exchange,UVa10763)

    题目描述: 解题思路: 开一个数组,读入一次交换两个数,如果最后数组不变,即符合匹配 #include<iostream> #include<cstdio> #include& ...

  2. OpenMPI运行问题:enough slots available in the system

    版本: Open MPI 3.0.1 编译好可执行的C语言程序后,使用 mpirun -np 3 Test 命令,发现没有正常运行,而是报错: There are not enough slots a ...

  3. 从wait_type入手模拟SQL Server Lock

    一.LCK_M_S,等待获取共享锁 开始一SQL TRAN,其中执行对某数据的UPDATE.但并不COMMIT,也不ROLLBACK. begin tran update [dbo].[HR_Empl ...

  4. 实用的ES6特性

    1. 函数参数默认值 不使用ES6 为函数的参数设置默认值: function foo(height, color) { var height = height || 50; var color = ...

  5. 《Linux编程大作业》

    一.要求 作业题目 Linux下的多进程/线程网络通信 作业目标 要求学生熟练掌握<Linux编程>课程中的知识点,包括Linux常用命令.bash脚本.编译和调试环境.读写文件.进程间通 ...

  6. ACM入门步骤(一)

    一般的入门顺序: 0. C语言的基本语法(或者直接开C++也行,当一个java选手可能会更受欢迎,并且以后工作好找,但是难度有点大),[参考书籍:刘汝佳的<算法竞赛入门经典>,C++入门可 ...

  7. 一步步学敏捷开发:1、敏捷开发及Scrum介绍

    敏捷开发之 历史背景 20世纪60年代:软件作坊,软件规模小,以作坊式开发为主:70年代:软件危机,硬件飞速发展,软件规模和复杂度激增,引发软件危机:80年代:软件过程控制,引入成熟生产制造管理方法, ...

  8. TCP系列22—重传—12、Forward Retransmit

    一.概述 forward retransmit相关的内容在RFC6675中有描述,可以参考RFC6675 section 4中NextSeg ()的定义.forward retransmit中文名可以 ...

  9. 把jar包加入本地maven库内

    1首先,在项目的pom.xml文件中加入 <dependency><groupId>taobao-alidayu</groupId>  //名字随便取不要跟已有的重 ...

  10. bpf移植到3.10

    bpf_common.h中显示的是/usr/src/linux-headersXXXX/include/uapi/linux 竟然会识别系统的挂载选项: