校省选赛第一场D题TwoDecks题解

2024-05-28 19:38

本文主要是介绍校省选赛第一场D题TwoDecks题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天晚上第二场比赛,现在还是赛后刷上次的题目,越刷越伤心,发现我赛后一次AC的功力很强大啊!!!(希望今晚变成是赛中一次AC啊!!)

好啦,回归正题。

看题目

D. Merging Two Decks

time limit per test

2 seconds

memory limit per test

256 megabytes

input

input.txt

output

output.txt

There are two decks of cards lying on the table in front of you, some cards in these decks lay face up, some of them lay face down. You want to merge them into one deck in which each card is face down. You're going to do it in two stages.

The first stage is to merge the two decks in such a way that the relative order of the cards from the same deck doesn't change. That is, for any two different cards i and j in one deck, if card i lies above card j, then after the merge card i must also be above card j.

The second stage is performed on the deck that resulted from the first stage. At this stage, the executed operation is the turning operation. In one turn you can take a few of the top cards, turn all of them, and put them back. Thus, each of the taken cards gets turned and the order of these cards is reversed. That is, the card that was on the bottom before the turn, will be on top after it.

Your task is to make sure that all the cards are lying face down. Find such an order of merging cards in the first stage and the sequence of turning operations in the second stage, that make all the cards lie face down, and the number of turns is minimum.

Input

The first input line contains a single integer n — the number of cards in the first deck (1 ≤ n ≤ 105).

The second input line contains n integers, separated by single spaces a1, a2, ..., an (0 ≤ ai ≤ 1). Value ai equals 0, if the i-th card is lying face down, and 1, if the card is lying face up. The cards are given in the order from the topmost one to the bottommost one.

The third input line contains integer m — the number of cards in the second deck (1 ≤ m ≤ 105).

The fourth input line contains m integers, separated by single spaces b1, b2, ..., bm (0 ≤ bi ≤ 1). Value bi equals 0, if the i-th card is lying face down, and 1, if the card is lying face up. The cards are given in the order from the topmost to the bottommost.

Output

In the first line print n + m space-separated integers — the numbers of the cards in the order, in which they will lie after the first stage. List the cards from top to bottom. The cards from the first deck should match their indexes from 1 to n in the order from top to bottom. The cards from the second deck should match their indexes, increased by n, that is, numbers from n + 1 to n + m in the order from top to bottom.

In the second line print a single integer x — the minimum number of turn operations you need to make all cards in the deck lie face down. In the third line print x integers: c1, c2, ..., cx (1 ≤ ci ≤ n + m), each of them represents the number of cards to take from the top of the deck to perform a turn operation. Print the operations in the order, in which they should be performed.

If there are multiple optimal solutions, print any of them. It is guaranteed that the minimum number of operations doesn't exceed 6·105.

Sample test(s)
Input
3
1 0 1
4
1 1 1 1
Output
1 4 5 6 7 2 3
3
5 6 7
Input
5
1 1 1 1 1
5
0 1 0 1 0
Output
6 1 2 3 4 5 7 8 9 10
4
1 7 8 9
同样,先解释一下题目:

有两叠扑克牌,我们要将他们合并在一起,并且让所有扑克牌都朝下

有两个操作:

第一步操作: 将两叠扑克牌合并在一起,但是要保持原来的子顺序,比如
A牌是 正反正   B牌是反正正

            1  2  3               4  5 6

合并之后不能是    3 1 2 4 5 6(3跑到1,2上面了!)但是可以是1 2 3 4 5 6 ,  4 5 6 1 2 3,1 4 2 5 6 3,……等等,子顺序要保持。

第二步操作: 抽出上面k张牌反转后放回去,直到所有扑克牌都朝下。

   比如合并后是 1 0 1  1 1

   那么我们抽第一张牌反转后放回去 0 0 1 1 1 ,再抽出前两张,反转放回1 1 1 1 1 ,再5张反转就变成0 0 0 0 0(0 表示向下,1表示向上)

问最少操作次数。

我的思路就是贪心啦!

合并的时候,以第一叠牌的第一张为基准形成情况1 frm,以第二叠牌第一张为基准形成情况2 lat.

之后对于每个情况,如果其中一叠的当前牌是相同状态就直接放进,不然放另外一叠牌的当前牌,力求最相同连续。

这样就得出两个情况对叠后的一副牌啦。

之后就从头开始反转,不同就翻转,最后使得所有的牌都一样状态,此时如果是1状态,就再做一次反转。

这样得出的结果是最优的,这个可以自己想象。

我的代码:

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux* Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)* Encoding     : UTF8* Date         : 2014-04-03* All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
class Pair
{
public:int ind,stat;Pair() {};Pair & operator =(Pair rhs){this->ind=rhs.ind;this->stat=rhs.stat;return *this;}};
int main()
{freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);int n,m,i,j,cntf,cntl;vector<Pair> a,b;vector<Pair> frm,lat;int a_i,b_i,f_i,l_i;while(cin>>n){a.clear();b.clear();frm.clear();lat.clear();a.resize(n);for(i=0; i<n; i++){cin>>j;a[i].ind=i+1;a[i].stat=j;}cin>>m;b.resize(m);frm.resize(n+m);lat.resize(n+m);for(i=0; i<m; i++){cin>>j;b[i].ind=n+i+1;b[i].stat=j;}//合并,以a为标准frm[0]=a[0];f_i=0;a_i=1;b_i=0;while(f_i<n+m-1){//cout<<"sb"<<f_i<<a_i<<b_i;;if((a_i<n&&frm[f_i].stat==a[a_i].stat)||b_i==m){f_i++;frm[f_i]=a[a_i];a_i++;}else{f_i++;frm[f_i]=b[b_i];b_i++;}}//合并以b为标准lat[0]=b[0];l_i=0;a_i=0;b_i=1;while(l_i!=n+m-1){if((b_i<m&&lat[l_i].stat==b[b_i].stat)|| (a_i==n)){l_i++;lat[l_i]=b[b_i];b_i++;}else{l_i++;lat[l_i]=a[a_i];a_i++;}}/*for(i=0;i<n+m;i++){cout<<frm[i].stat<<" ";}cout<<endl;for(i=0;i<n+m;i++){cout<<lat[i].stat<<" ";}cout<<endl;*///对frm测试cntf=cntl=0;int stat=frm[0].stat;for(f_i=1; f_i<n+m; f_i++){if(frm[f_i].stat!=stat){stat=frm[f_i].stat;cntf++;}}if(stat==1){cntf++;}stat=lat[0].stat;for(l_i=1; l_i<n+m; l_i++){if(lat[l_i].stat!=stat){stat=lat[l_i].stat;cntl++;}}if(stat==1){cntl++;}if(cntl<cntf){for(i=0;i<n+m;i++){cout<<lat[i].ind<<" ";}cout<<endl;cout<<cntl<<endl;stat=lat[0].stat;for(l_i=1; l_i<n+m; l_i++){if(lat[l_i].stat!=stat){stat=lat[l_i].stat;cout<<l_i<<" ";}}if(stat==1){cout<<l_i;}cout<<endl;}else{for(i=0;i<n+m;i++){cout<<frm[i].ind<<" ";}cout<<endl;cout<<cntf<<endl;stat=frm[0].stat;for(f_i=1; f_i<n+m; f_i++){if(frm[f_i].stat!=stat){stat=frm[f_i].stat;cout<<f_i<<" ";}}if(stat==1){cout<<f_i<<" ";}cout<<endl;}}fclose(stdin);fclose(stdout);return 0;}



这篇关于校省选赛第一场D题TwoDecks题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1011506

相关文章

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>

P2858 [USACO06FEB] Treats for the Cows G/S 题解

P2858 题意 给一个数组。每天把最左或者最右的东西卖掉,第 i i i个东西,第 d a y day day天卖出的价格是 a [ i ] ∗ d a y a[i]*day a[i]∗day。 记忆化搜索 void dfs(int l,int r,int day,ll sum){if(v[l][r]>=sum)return;v[l][r]=sum;if(l>r)//这就是dp答案{

【C++题解】1272. 郭远摘苹果

欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》 问题:1272. 郭远摘苹果 类型:二维数组 题目描述: 郭远有一天走到了一片苹果林,里面每颗树上都结有不同数目的苹果,郭远身上只能拿同一棵树上的苹果,他每到一棵果树前都会把自己身上的苹果扔掉并摘下他所在树上的苹果并带走(假设郭远会走过每一棵苹果树),问在郭远摘苹果的整个过程中,他身上携带的最多苹果数与最小苹果数的差是多少?

【最新华为OD机试E卷-支持在线评测】机器人活动区域(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-E/D卷的三语言AC题解 💻 ACM金牌🏅️团队| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线评测,专栏文章质量平均 94 分 最新华为OD机试目录: https://blog.

2023 CCPC(秦皇岛)现场(第二届环球杯.第 2 阶段:秦皇岛)部分题解

所有题目链接:Dashboard - The 2023 CCPC (Qinhuangdao) Onsite (The 2nd Universal Cup. Stage 9: Qinhuangdao) - Codeforces 中文题面: contest-37054-zh.pdf (codeforces.com) G. Path 链接: Problem - G - Codeforces