P9900 『PG2』消除萝卜 B 题解
题意简述
有
- 花
1 的代价,选一个有萝卜的位置,将这个萝卜所在的由同种颜色萝卜构成的四连通极大连通块的萝卜全部拿走。若在第i-1 行有一个没有萝卜的空位,则第i 行的萝卜就会掉落至第i-1 行。 - 同时你也可以花初始为
0 的代价,选定k 而将第k 列的所有萝卜上移,并将一个红萝卜即1 放在第一行第k 个,此后这个操作代价+1 。
求拿走所有萝卜的最小代价。
解题思路
题目中有一个重要的提示,即保证
友情提示
- 由于本题数据较强,对于 c++ 语言,以
O(n) 的时间复杂度纯用cin输入都难以通过,所以可以尝试使用快读输入。 快读模板如下:int read(){ int ret=0;bool sgn=false;int ch=getchar(); while(!isdigit(ch))sgn|=ch=='-',ch=getchar();//isdigit()为判断字符是否为数字的函数 while(isdigit(ch))ret=ret*10+ch-'0',ch=getchar(); return sgn?-ret:ret;//三目运算符 } - 使用
inline可以将函数定义为内联函数,有效地优化函数,感兴趣的读者可以自行上网查阅代码展示
#include<bits/stdc++.h> using namespace std; inline int read(){//定义为内联函数 bool k=0;char c=getchar();//由于k只有一位,所以用bool类型存即可 while(!isdigit(c))c=getchar();//k不可能为负数 while(isdigit(c))k=c^'0',c=getchar();//k不可能进位(c^'0'等同于c-'0') return k; }int n,ans=1; bool a[5000005];//只需任存一列即可 int main(){ scanf("%d",&n),a[0]=read(),read();//第二个read()用来过滤第二列数据 for(int i=1;i<n;i++)a[i]=read(),read(),ans+=a[i]!=a[i-1];//若a[i]!=a[i-1],则ans++ printf("%d",1+(ans+1>>1));//输出答案(同printf("%d",1+(int)ceil(1.0*ans/2));) return 0; }