Codeforces Round #577 (Div 2)
A. Important Exam
水题
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int maxx = ;
char a[maxx][maxx];
int pre[maxx];
int b[maxx];
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
for (int i=;i<n;i++){
scanf("%s",a[i]);
}
for (int i=;i<m;i++){
scanf("%d",&b[i]);
}
for (int i=;i<m;i++){
int sum[]={,,,,};
for (int j=;j<n;j++){
if (a[j][i]=='A'){
sum[]++;
}else if (a[j][i]=='B'){
sum[]++;
}else if (a[j][i]=='C'){
sum[]++;
}else if (a[j][i]=='D'){
sum[]++;
}else {
sum[]++;
}
}
int maxx=;
for (int i=;i<=;i++){
maxx=max(maxx,sum[i]);
}
pre[i]=maxx;
}
long long ans=;
for (int i=;i<m;i++){
ans+=(long long)pre[i]*b[i];
}
printf("%lld\n",ans);
}
return ;
}
B. Zero Array
这道题就非常难受了
题意就是说,你有一个序列,你每次可以选择两个数,使得这两个数的值减小1。
最开始不知道为啥,脑子短路了,我发现只要把最大的减去最小的,然后用剩下的去减次小的,用剩下的继续减去
而且找不到反例,后面同学讨论一波,同学提出了一个2,2,2的样例,瞬间把我的结论推翻了。
后面也发现了我的结论的不正确,因为我每次把最大的减去次大的,那么不可避免的产生了一个新的数,这个数的大小我们没法判断,如果这个值过小,但是后面还有一个比这个值大的数。其实就不正确的。
其实你可以这样想,既然要求有没有可能,我们的顺序最优秀的,我们发现,其实每次把最高的降到次高的即可。这样我们保证一定是最有效的。但是有两个特殊情况,一个是数的总和是奇数那么无论怎么样
都会剩下一个。还有就是最高的太高了,用其他的所有都不能降到0,特判这两种情况即可
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL long long
using namespace std;
const int maxx = 1e5+;
int a[maxx];
LL sum;
int main(){
int n;
while(~scanf("%d",&n)){
sum=;
for (int i=;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
sort(a+,a++n);
if (sum%== && sum-a[n]>=a[n]){
printf("YES\n");
}else {
printf("NO\n");
}
}
return ;
}
C. Maximum Median
每次对一个数+1,一共可以进行K次,问最大中位数是多少。
二分答案即可
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#define LL long long
using namespace std;
const int maxx = ;
LL a[maxx];
LL n,k;
bool check(LL x){
LL ans=;
for (int i=(n+)/;i<=n;i++){
if (a[i]<x){
ans=(LL)ans+x-a[i];
}
}
if (ans<=k)return true;
else return false;
}
int main(){
while(~scanf("%lld%lld",&n,&k)){
for (int i=;i<=n;i++){
scanf("%lld",&a[i]);
}
sort(a+,a++n);
LL l=a[(n+)/],r=3e9;
LL ans=l;
while(l<=r){
LL mid=(l+r)/;
if (check(mid)){
ans=mid;
l=mid+;
}else {
r=mid-;
}
}
printf("%lld\n",ans);
}
return ;
}
D. Treasure Hunting
好题啊,这个题真的很秀,当时没看到这个题,后面看别人的代码+题解,懂了
题目意思是,给一些的坐标点,坐标点上会有宝藏,你可以在每一行中随意移动,并在指定的列中往下移动,问如何移动能收集所有的宝藏,同时使得移动的步数最少
你可以发现以下结论
1.我们在每一层搜集完了所有的宝藏后,应该尽快往下一层走。搜集完所有的时刻,一定是在某一个边界位置,可能是左边界,也有可能是右边界
2.我们每次下到新的一层,一定是从边界位置开始(因为那个时候刚好收集完成),向左走,找到最近的向下走的通道,或者向右走,找到最近向下走的通道
3.我们到达新的一层后,需要判断是否这一层有宝藏
4.如果有宝藏,我们需要考虑,是先往左走搜集完左边的,然后再向右走收集到最右边的,还是先向右走搜集完右边的,然后向左走搜集完最左边的
有了这个,我们的DP就非常好写了
转移方程为
dp[i][0]表示收集完第i层,最后在最左边
dp[i][1]表示收集完第i层,最后在最右边
用trans()计算从第j层边界到i层边界,水平移动的步数。
那么转移方程可以写为:
dp[][]=abs(maxn[][]-)+abs(maxn[][]-maxn[][]);
//从起点开始,走到最右边,再走回来
dp[][]=abs(maxn[][]-);
//从起点开始,走到最右边
dp[i][]=min(dp[i][],dp[j][]+trans(j,,i,)+i-j);
dp[i][]=min(dp[i][],dp[j][]+trans(j,,i,)+i-j);
dp[i][]=min(dp[i][],dp[j][]+trans(j,,i,)+i-j);
dp[i][]=min(dp[i][],dp[j][]+trans(j,,i,)+i-j);
前两个都是计算初始值
四个分别表示
从第j层左边界最后到第i层左边边界,搜集完第i层所需要的步数
从第j层左边界最后到第j层右边边界,搜集完第i层所需要的步数
从第j层右边界最后到第j层左边边界,搜集完第i层所需要的步数
从第j层右边界最后到第j层右边边界,搜集完第i层所需要的步数
最后在找边界的从左右两边找到最近的通道,用二分查找即可。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<vector>
#define LL long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=j;i>=k;i--)
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
using namespace std;
using namespace std;
const int maxx = 2e5+;
const int INF = 1e9;
LL maxn[maxx][];
LL dp[maxx][];
int n,m,k,q;
int b[maxx];
LL trans(int u,int du,int v,int dv){
int p=lower_bound(b+,b++q,maxn[u][du])-b;
LL rt=INF;
//找到第一个小于maxn[u][du]
if(p<=q){
rt=abs(maxn[u][du]-b[p])+abs(maxn[v][dv^]-b[p])+abs(maxn[v][dv]-maxn[v][dv^]);
//我们找到abs(maxn[u][du]-b[p])+abs(maxn[v][dv^1]-b[p])+abs(maxn[v][dv]-maxn[v][dv^1])了一条路后,水平消耗的路程,应该是出发点的通路的距离,以及到达目的层后,目标方向的反向的最远距离,以及目标防方向的最远距离
}
p=upper_bound(b+,b++q,maxn[u][du])-b-;
if(p){
rt=min(rt,abs(maxn[u][du]-b[p])+abs(maxn[v][dv^]-b[p])+abs(maxn[v][dv]-maxn[v][dv^]));
}
return rt;
}
int main(){
while(~scanf("%d%d%d%d",&n,&m,&k,&q)){
rep(i,,n){
maxn[i][]=INF;
maxn[i][]=-INF;
}
LL x,y;
rep(i,,k){
scanf("%lld%lld",&x,&y);
maxn[x][]=min(maxn[x][],y);
maxn[x][]=max(maxn[x][],y);
}
maxn[][]=;
maxn[][]=max(maxn[][],1LL);
rep(i,,q){
scanf("%d",&b[i]);
}
sort(b+,b++q);
memset(dp,0x3f,sizeof(dp));
dp[][]=abs(maxn[][]-)+abs(maxn[][]-maxn[][]);
//从起点开始,走到最右边,再走回来
dp[][]=abs(maxn[][]-);
//从起点开始,走到最右边
int j=;
rep(i,,n){
if (maxn[i][]==INF)continue;
dp[i][]=min(dp[i][],dp[j][]+trans(j,,i,)+i-j);
dp[i][]=min(dp[i][],dp[j][]+trans(j,,i,)+i-j);
dp[i][]=min(dp[i][],dp[j][]+trans(j,,i,)+i-j);
dp[i][]=min(dp[i][],dp[j][]+trans(j,,i,)+i-j);
j=i;
}
printf("%lld\n",min(dp[j][],dp[j][]));
}
return ;
}
Codeforces Round #577 (Div 2)的更多相关文章
- Codeforces Round #577 (Div. 2) D. Treasure Hunting
Codeforces Round #577 (Div. 2) D. Treasure Hunting 这个一场div2 前面三题特别简单,这个D题的dp还是比较难的,不过题目告诉你了只能往上走,所以 ...
- 矩阵拿宝物--Codeforces 1201D - Treasure Hunting Codeforces Round #577 (Div. 2)
网上题解比较少,自己比较弱研究了半天(已经过了),希望对找题解的人有帮助 题目链接:https://codeforc.es/contest/1201/problem/D 题意: 给你一个矩形,起始点在 ...
- Codeforces Round #577 (Div. 2) 题解
比赛链接:https://codeforc.es/contest/1201 A. Important Exam 题意:有\(n\)个人,每个人给出\(m\)个答案,每个答案都有一个分值\(a_i\), ...
- Codeforces Round #577 (Div. 2) C. Maximum Median (模拟,中位数)
题意:给你一个长度为奇数\(n\)的序列.你可以对任意元素加上\(k\)次\(1\),求操作后的中位数最大. 题解:先对序列进行排序,然后对中位数相加,如果中位数和后面的元素相等,就对后面所有和当前中 ...
- Codeforces Round #577 (Div. 2) C. Maximum Median
题意:就是给一n(奇数)个元素数组,可以对它的元素执行k次+1操作,递增排序,求中位数最大是多少. 那我们在排完序之后,中位数前的元素可以不管它,只要对中位数后的操作就行,我们要判断和中位数相等的元素 ...
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
随机推荐
- Handling Missing Values
1) A Simple Option: Drop Columns with Missing Values 如果这些列具有有用信息(在未丢失的位置),则在删除列时,模型将失去对此信息的访问权限. 此外, ...
- QT_强杀进程
#ifdef WIN32 bool res = false; HANDLE hToolHelp32Snapshot; hToolHelp32Snapshot = CreateToolhelp32Sna ...
- 如何把pdf文档转化为word
在工作中常常遇到大量的pdf文档,再加工进行处理文件,特别的不方便,需要转换为WORD. 尝试如下: 使用wps自带的工具转换,提示需要是会员才能进行.否则只能进行5页以下的转换. 再想是不是又有个这 ...
- 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树
题面 在Byteland一共有n 个城市,编号依次为1 到n,它们之间计划修建m条双向道路,其中修建第i 条道路的费用为ci. Byteasar作为Byteland 公路建设项目的总工程师,他决定选定 ...
- Codeforces Beta Round #77 (Div. 2 Only) A. Football【字符串/判断是否存在连续7个0或7个1】
A. Football time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...
- [Vue CLI 3] 配置解析之 css.extract
大家还记得我们在老版本中,对于线上环境配置中会把所有的 css 多打成一个文件: 核心是使用了插件 extract-text-webpack-plugin,方式如下: 第一步都是加载插件 const ...
- 写GULP遇到的ES6问题详解
Gulp.js 是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务.最近复习一下gulp一些基本的写法,在写了一些简单的uglify,rename,concat,clean的处理之 ...
- NOIP模拟 7.04
魔术球问题弱化版(ball.c/.cpp/.pas) [题目描述] 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球. (1)每次只能在某根柱子的最上面放球. ( ...
- 【水滴石穿】react-native-book
先推荐一个学习的地址:https://ke.qq.com/webcourse/index.html#cid=203313&term_id=100240778&taid=12778558 ...
- 使用curl指令实现restful接口操作
curl 是很方便的Rest客戶端,可以很方便的完成許多Rest API測試的需求,甚至,如果是需要先登入或認證的rest api,也可以進行測試,利用curl指令,可以送出HTTP GET, POS ...