CodeForces 159E
题目大意:
给定一堆带颜色和高度的魔方
用两种颜色的魔方,一种颜色接一种颜色向上拼接搭建成一个高塔,求高塔的最长高度,以及将拼接的过程中对应的编号顺序输出
多种情况成立输出任意一种即可
这里首先要对颜色(c值)进行离散化,这样每种颜色都对应有一个编号
用一个响亮vec[i]来保存 编号 i 的颜色的高度值以及对应要输出时的序号 , 高度值由大到小保存,这个可以在一开始的魔方排序给c离散化的时候做到
拼接可以是两种颜色各有 len 个 , 或者一种为len , 一种为len+1
那么利用一个数组max_val [len] , sec_val[len]保存有len个颜色相同的魔方所能构建的最大和次大值
那么同时也要建立max_id[len] , sec_id[len]表示len个颜色相同的魔方所能构建的最大和次大值时对应的 颜色离散化后的标号
每次不断往向量中加入一个魔方的情况,加的同时就可以对上述的4个数组进行更新,因为 s 由大到小排列,那么加的时候始终得到的是当前颜色这个长度所能达到的最大
这样就可以max_val [len] , sec_val[len]来求最大值,中间找到最大值时,记录一些相关数据以便最后的输出
每次找的时候要写一个判断保证这个条件下所得到的两种魔方不为一个颜色
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
const int N = ; int a[N] , max_id[N] , sec_id[N]; //a[]保存离散化后的c struct Node{
int v , num;
}; vector<Node> vec[N];
#define ll long long
ll max_val[N] , sec_val[N] , sum[N]; struct Cube{
int c , s , num;
bool operator<(const Cube &m)const{
if(c == m.c) return s > m.s;
return c < m.c;
}
}cu[N]; int bin_search(int x , int k)
{
int l= , r = k-;
while(l<=r){
int m=(l+r)>>;
if(a[m] == x) return m;
else if(a[m]>x) r = m-;
else l = m+;
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int n;
while(scanf("%d" , &n ) == )
{
for(int i= ; i<=n ; i++) vec[i].clear(); for(int i = ;i<n ; i++)
{
scanf("%d%d" , &cu[i].c , &cu[i].s);
cu[i].num = i+;
} sort(cu , cu+n);
int k = ;
a[k++] = cu[].c;
for(int i= ; i<n ; i++){
if(cu[i].c != cu[i-].c) a[k++] = cu[i].c;
} memset(sum , , sizeof(sum));
memset(max_val , , sizeof(max_val));
memset(sec_val , , sizeof(sec_val));
for(int i= ; i<n ; i++){
int index = bin_search(cu[i].c , k);
Node node;
node.num = cu[i].num , node.v = cu[i].s;
vec[index].push_back(node);
sum[index] = sum[index] + cu[i].s;
int len = vec[index].size();
if(max_val[len] < sum[index]){
sec_val[len] = max_val[len];
sec_id[len] = max_id[len]; max_val[len] = sum[index];
max_id[len] = index;
}
else if(sec_val[len] < sum[index]){
sec_val[len] = sum[index];
sec_id[len] = index;
}
}
// cout<<"test: "<<max_val[1]<<" index: "<<max_id[1]<<" "<<sec_id[1]<<endl;
int col1 , col2 , len1 , len2;
ll ans = ;
for(int len= ; len<=n ; len++){
if(max_val[len] && sec_val[len]){
if(max_id[len] != sec_id[len]){
if(ans < max_val[len]+sec_val[len]){
ans = max_val[len]+sec_val[len];
col1 = max_id[len];
col2 = sec_id[len];
len1 = len , len2 = len;
}
}
}
//长度不等的时候排除所有两种颜色一样的情况
if(max_val[len] && max_val[len+]){
if(max_id[len] != max_id[len+]){
if(ans < max_val[len]+max_val[len+]){
ans = max_val[len]+max_val[len+];
col1 = max_id[len];
col2 = max_id[len+];
len1 = len , len2 = len+;
}
}
}
if(sec_val[len] && max_val[len+]){
if(sec_id[len] != max_id[len+]){
if(ans < sec_val[len]+max_val[len+]){
ans = sec_val[len]+max_val[len+];
col1 = sec_id[len];
col2 = max_id[len+];
len1 = len , len2 = len+;
}
}
}
if(max_val[len] && sec_val[len+]){
if(max_id[len] != sec_id[len+]){
if(ans < max_val[len]+sec_val[len+]){
ans = max_val[len]+sec_val[len+];
col1 = max_id[len];
col2 = sec_id[len+];
len1 = len , len2 = len+;
}
}
}
} printf("%I64d\n%d\n" , ans , len1+len2);
printf("%d" , vec[col2][].num);
for(int i= ; i<len1 ; i++){
printf(" %d" , vec[col1][i].num);
if(i+<len2) printf(" %d" , vec[col2][i+].num);
}
puts("");
}
return ;
}
CodeForces 159E的更多相关文章
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
- 【Codeforces 738A】Interview with Oleg
http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...
- CodeForces - 662A Gambling Nim
http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...
- CodeForces - 274B Zero Tree
http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...
- CodeForces - 261B Maxim and Restaurant
http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...
- CodeForces - 696B Puzzles
http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...
- CodeForces - 148D Bag of mice
http://codeforces.com/problemset/problem/148/D 题目大意: 原来袋子里有w只白鼠和b只黑鼠 龙和王妃轮流从袋子里抓老鼠.谁先抓到白色老鼠谁就赢. 王妃每次 ...
随机推荐
- 离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers
题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前 ...
- java数组实现红包的方法
package Hongbao; import java.text.DecimalFormat; import java.util.Scanner; public class Hongbao { pu ...
- UML 活动图(转载)
活动图:用于表示系统中各种活动的次序,它的应用非常广泛,即可用来描述用例的工作流程,也可用来描述类中某个方法的操作行为.常用于表示业务流程,对系统功能建模,强调对象之间的控制流.活动图是由状态图变化而 ...
- 冒泡排序算法和简单选择排序算法的js实现
之前已经介绍过冒泡排序算法和简单选择排序算法和原理,现在有Js实现. 冒泡排序算法 let dat=[5, 8, 10, 3, 2, 18, 17, 9]; function bubbleSort(d ...
- iOS-UI控件之UITableView(二)- 自定义不等高的cell
不等高的cell 给模型增加frame数据 所有子控件的frame cell的高度 @interface XMGStatus : NSObject /**** 文字\图片数据 ****/ // ... ...
- glm 矩阵乘法得反过来写
- iTOP4418开发板7寸屏幕Android系统下横竖屏设置
Android系统屏幕旋转设置 平台: iTOP4418开发板+7寸屏幕 1. Androd4.4源码可以编译成手机模式和平板模式,讯为iTop4418 开发平台的Android系统默认编译为平板模式 ...
- eclipse自动为变量生成Get/Set函数
启动Eclipse,打开demo工程.如图: 假定为成员变量test生成Get/Set函数. 光标定位到该成员变量,如图: 右键选择“source”-“Generate Getters and ...
- DEALLOCATE - 删除一个准备好的查询
SYNOPSIS DEALLOCATE [ PREPARE ] plan_name DESCRIPTION 描述 DEALLOCATE 用于删除前面准备好的查询. 如果你没有明确 DEALLOCATE ...
- java_udp编程
两个重要的类: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/DatagramPacket.html ht ...