Codeforces Round #631 (Div. 2) - Thanks, Denis aramis Shitov! 比赛人数10889
[codeforces 1330C] Dreamoon Likes Coloring 极端处理,再图变通
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1330/problem/C
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
C - Dreamoon Likes Coloring | GNU C++11 | Accepted | 61 ms | 900 KB |
题意理解是关键,
cell will have the color from the latest operation.
all colors will appear at least once and all cells will be colored.
从以上两句可以看到,约束条件是,所有格子都被染色,并且每一种颜色都能被看到。
思路:
手工模拟:
用最紧凑方式安排颜色,即1个格子1种颜色,但不可行的样例
用最紧凑方式安排颜色,即1个格子1种颜色,但不可行的样例
Input:
5 3
1 1 4
Output:
0
颜色i 1 2 3
l[i] 1 1 4
可摆放格子的区间 [1,5] [1,5] [1,2]
可以看到,颜色1摆放到格子1,可行;颜色2摆放到格子2,可行;
颜色3摆放到格子3,不可行,因颜色3可拜放的格子区间是[1,2].
用最宽松方式安排颜色,i种颜色摆放在l[i]个格子中,但不可行的样例
用最宽松方式安排颜色,i种颜色摆放在l[i]个格子中,但不可行的样例
Input:
5 2
2 2
Output:
0
颜色1摆放在的格子区间[1,2]
颜色2摆放在的格子区间[3,4]
很明显,格子区间[5],无染色,故不可行。
但上面2种颜色,已经尽了最大努力。
界于最紧凑颜色摆放,与最宽松颜色摆放之间,可行的样例。逆向处理
界于最紧凑颜色摆放,与最宽松颜色摆放之间,可行的样例。逆向处理
Input:
5 3
3 2 2
Output:
2 4 1
先按最紧凑颜色摆放
颜色1摆放在格子1,颜色2摆放在格子2,颜色3摆放在格子3
此时,还有[4,5]区间这2个格子未染色,
取出颜色3,此时[3,5]区间这3个格子未染色,
颜色3尽最大努力,能将[4,5]区间这2个格子染色,让颜色3的p[3]=4,此时还剩格子3未染色。
取出颜色2,此时[2,3]这2个格子未染色,
颜色2尽最大努力,能将[2,3]这2个格子染色,让颜色2的p[2]=2,此时所有格子均已染色。
根据上述手工模拟,编写的AC代码如下,当然同一个思路,不同人写出的代码,还是会有很大差异。
#include <stdio.h>
#define maxn 100010
#define LL long long
int l[maxn],p[maxn];
LL sum;
int main(){
int i,n,m,flag=0;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
p[i]=i;//用最紧凑的方法安排颜色,一个颜色放一格
scanf("%d",&l[i]),sum+=l[i];//用最宽松的方法安排颜色,颜色i放l[i]个格子
if(i>n-l[i]+1)flag=1;//用最紧凑的方法,发现p[i]不在 [1,n−li+1] 区间。
}
if(sum<n)flag=1;//用最紧凑的方法,发现填不满格子
if(flag){
printf("-1\n");
return 0;
}
p[m+1]=n+1;//边界设置
n-=m;//计算后的n表示还需染色的格子
for(i=m;i>=1;i--){//结尾宽松设置颜色,开头紧凑设置颜色。
if(l[i]>n)break;
else n-=l[i]-1,p[i]=p[i+1]-1-(l[i]-1);
}
for(i=1;i<m;i++)printf("%d ",p[i]);
printf("%d\n",p[m]);
return 0;
}