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. 为什么Python在列表和元组的末尾允许使用逗号?

    Python 允许您在列表,元组和字典的末尾添加一个尾随逗号: [1, 2, 3,] ('a', 'b', 'c',) d = { "A": [1, 5], "B&quo ...

  2. 372. Delete Node in a Linked List【LintCode java】

    Description Implement an algorithm to delete a node in the middle of a singly linked list, given onl ...

  3. popen()与system()

    一.popen() 用途:执行shell命令(并读取其输出或向其发送一些输入) 特点:通过管道来与shell命令进行通信 二.system()

  4. 自测之Lesson7:设备文件操作

    题目:请编写一个输入密码(不回显)的程序,要求通过设置终端来完成. 完成代码: #include <stdio.h> #include <unistd.h> #include ...

  5. java利用POI实现读取Word并获取指定样式的文本

    import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.model.StyleDescription; import o ...

  6. c#和.net区别

    .net 包含两大部分:.net framework类库和公共语言运行库(CLR) .net framework类库,就是微软工程师写好的各种功能类,例如math类. 公共语言运行库:1.与操作系统进 ...

  7. Java微笔记(4)

    Java 中的内部类 内部类( Inner Class )就是定义在另外一个类里面的类.与之对应,包含内部类的类被称为外部类 内部类的主要作用如下: 内部类提供了更好的封装,可以把内部类隐藏在外部类之 ...

  8. Java微笔记(1)

    一,Arrays 类是 Java 中提供的一个工具类,在 java.util 包中.该类中包含了一些方法用来直接操作数组,比如可直接实现数组的排序.搜索 1. 排序 语法: Arrays.sort(数 ...

  9. 数据库集群之路二 MYCAT

    windows下安装配置并使用mycat 参考:http://www.cnblogs.com/parryyang/p/5758087.html 一 下载windows版本 https://github ...

  10. lol人物模型提取(八)

      今天顺风终于把包裹送到了北航新主楼自提柜,怀着激动喜悦的心情,我小心翼翼地将其取回.   到了晚上,是时候解开佐伊的封印了!   开了个小口,发现里面包得还挺严实的.   去掉了纸盒,里面还有一层 ...