您的位置:首页 > 运维架构

【codeforces 733 C】【模拟】C. Epidemic in Monstropolis【给你n个数,再给你k个数,问你a序列能否通过一定规则合并变成b序列】

2016-11-01 19:46 429 查看
传送门:http://codeforces.com/contest/733/problem/C

题意:给你n个数,a1,a2,a3,…an,再给你k个数b1,b2,b3,…bk,问你a序列能否通过合并变成b序列。合并的条件为只能相邻的数合并并且由大数向小数合并,然后通过新序列合并下去问你能不能达到b序列?能达到的话输出是如何合并的,不能的话输出NO。

思路:

1、我们可以把a序列分成k个连续的块,每个块的值的总和与b对应,对于每个块我们单独处理下,我们可以这个块的最大值开始向两边合并,切存在相邻的数小于它,然后一直合并下去就可以了

2、但这里有几个注意点,每个块不能合并的条件为这个块里所有元素都相等且块的长度不为1、b的总和和a的总和要相等。

PS:这题主要是看细节和码力

代码:

#include <bits/stdc++.h>
using  namespace  std;

#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define rep(i,k,n) for(int i=k;i<=n;i++)
#define rrep(i,k,n) for(int i=k;i>=n;i--)

template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}

int k, n;

int  main(){
std::vector<int> a;
read(n);
rep(i, 1, n){
int x; read(x);
a.pb(x);
}
read(k);
int it = 0;
std::vector<pair<int, char> > ans;
rep(i, 0, k - 1){
set<int>h;
int x;read(x);
int v = 0, l = it, mx = -1;
while(it < n && a[it] + v <= x){
v += a[it]; //分块和
mx = max(mx, a[it]); //分块的最大值
h.insert(a[it]); //用于判断分块区域是否全等
it++;   //当前指针
}
int r = it;
//a序列变不了b序列或者分块的序列中值全相等都是不行的
if(v != x || h.size() == 1 && l + 1 < r)return 0 * puts("NO");

r--;
rep(j, l + 1, r){

if(max(a[j], a[j - 1]) == mx && min(a[j], a[j - 1]) != mx){//样例221
if(a[j - 1] == mx){
rep(k, j, r){
ans.pb(mp(j - l + i, 'R'));//一直往右吃
}
rrep(k, j - 1, l + 1){
ans.pb(mp(k - l + 1 + i, 'L'));//一直往左吃
}
}
else{
rrep(k, j, l + 1){
ans.pb(mp(k - l + 1 + i, 'L'));//一直往左吃
}
rep(k, j, r - 1){
ans.pb(mp(i + 1, 'R'));//一直往右吃
}
}
break;
}

}
}
if(ans.size() != n - k)return 0 * puts("NO");
puts("YES");
for(auto x : ans)printf("%d %c\n", x.ff, x.ss);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: