Codeforces Round #547 (Div. 3) 题解
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) 题解的更多相关文章
- Codeforces Round #182 (Div. 1)题解【ABCD】
Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...
- Codeforces Round #608 (Div. 2) 题解
目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...
- Codeforces Round #525 (Div. 2)题解
Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...
- Codeforces Round #528 (Div. 2)题解
Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...
- Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F
Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...
- Codeforces Round #677 (Div. 3) 题解
Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...
- Codeforces Round #665 (Div. 2) 题解
Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...
- Codeforces Round #160 (Div. 1) 题解【ABCD】
Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...
- 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 题解 直接 ...
随机推荐
- linux学习总结----mongoDB总结
dbhelper.py 用户登录和注册(加密算法) 加密导包 import hashlib 或者使用Md5 加密 MongoDB ->JSON service mysql start servi ...
- JavaScript 之 对象/JSON/数组
对象 简单说,所谓对象,就是一种无序的数据集合,由若干个“键值对”(key-value)构成. var obj = { p: 'Hello World' }; 上面代码中,大括号就定义了一个对象,它被 ...
- Java学习笔记-11.运行期间类型鉴定
1.Class对象的getClasses()方法获取的是该类中所有的公共的内部类,以及从父类,父接口继承来的内部类.getinterfaces()方法返回类继承的所有接口. import javax. ...
- 完全背包问题 :背包dp
题目描述: 有 N种物品和一个容量是 V 的背包,每种物品都有无限件可用.第 i 种物品的体积是 vi,价值是 wi. 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大.输出最 ...
- fp-growth树创建代码及详细注释
事务集过滤重排: #FP树节点结构 class treeNode: def __init__(self,nameValue,numOccur,parentNode): self.name=nameVa ...
- qt qchart缩放后坐标轴间隔取整
使用qt的qchart显示数据曲线,坐标轴QValueAxis可以设置刻度间隔数量,但每个刻度的数值是根据坐标的极值除以间隔数量得到的,不一定是整数,导致曲线控件的显示刻度不适合观察. 如图: 纵坐标 ...
- 七:HDFS Permissions Guide 权限
1.权限模式 简单:启动HDFS的操作系统用户即为超级用户,可以通过HADOOP_USER_NAME指定 kerberos: 2.group mapping 组列表由grou ...
- c# 生成的没用文件
1.pdb 2.vhost 3.application 4.含有更新功能(更新文件夹)
- python学习笔记04:安装pip
如果是从python官网下载的python版本(2.7.9或3.4)的安装包,其中已经内置了pip工具.那么只需要升级pip即可. 检测是否已安装pip: python -m pip --versio ...
- phpshell提权
实际操作中可以在webshell用udf.dll提权,用函数的上传文件功能上传文件到启动目录,再用shut函数重起系统.(目前没成功过,有 机会本地测试一下,先记录在这了).如果是英文版的系统,启动目 ...