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只黑鼠 龙和王妃轮流从袋子里抓老鼠.谁先抓到白色老鼠谁就赢. 王妃每次 ...
随机推荐
- java数组实现买彩票(阿基老师的打乱排序思想)
package com.wh.array; public class Lottery { public static void main(String[] args) { int[] num=new ...
- Discrete Logging
Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5865 Accepted: 2618 ...
- 移动端rem
手机有很多尺寸的型号.使用rem来做为大小单位可以达到兼容的目的. 方法一:js测量手机尺寸,设置font-size:为手机屏幕width /10 + ‘px’.即10rem 为手机屏幕width. ...
- 关于mapState和mapMutations和mapGetters 和mapActions辅助函数的用法及作用(三)-----mapGetters
简单的理解: const getters = { newCount: function(state){ return state.count += 5; } } ------------------- ...
- vue2.0 路由知识一(路由的创建的全过程)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- HDU_1710_二叉树前序中序确定后序
2018-3-6 按照王道机试书上的思路再做了一遍,先根据先序和中序建树,然后后序遍历. 静态分配数组用于建树,可以返回数组地址当作结点指针. #include<iostream> #in ...
- HTML a标签的href 属性 tel 点击可以直接拨打电话 ( 移动端 )
<a href="tel:13828172679">13622178579</a>
- 手机端打开调试工具,模拟console.log
将下列代码考入需要调试页面即可 <script src="//cdn.jsdelivr.net/npm/eruda"></script> <scrip ...
- CE工具里自带的学习工具--第一关
点击[下一步],进入第二关
- redis新特性
摘自<redis 4.xcookbook> 从实例重启同步] 故障切换同步] 4.0之前从实例主键过期bug redis4新特性 Memory Command Lazy Free PSYN ...