2018湖南ACM省赛

D:卖萌表情

//✔48ms(1000ms)
/*theme:已知以下 4 种都是卖萌表情(空白的部分可以是任意字符。竖线是便于展示的分隔符,没有实际意义):
 ^ ^ |  ^  | <  |  >
  v  | v v |  > | <
     |     | <  |  >
(多组)给出n行m列的字符矩阵,找出互不重叠的卖萌表情数量的最大值.互不重叠的意思是每个字符只属于至多一个卖萌表情。
1≤n,m≤1000,矩阵只包含 ^, v, <, > 4 种字符.n × m 的和不超过 2×10^6.
*
*
*
*
*
solution:可分为两组分开算(左边两种和右边两种互不影响),由于遍历时从左上开始,右边两种没有冲突情况,所以只需遍历求个数即可
而左边两种可能存在^<^<^<^<^最优解,因为遍历是是以'^'为基准找下一行'v'匹配,但 ^ 比^ ^的'v'更靠左,即对v的利用率越高
                  <v<v<v<v<                                                v v   v
由贪心思想,应优先考虑第二种再选第一种,注意选中后要标记为已选(可改为其他符号),避免重复
*/

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

char a[1100][1100];
int n,m;

int solve1()
{
    int cnt=0;
    for(int i=0;i<n-1;++i)
        for(int j=0;j<m-1;++j)
            if(a[i][j]=='^')
            {
                if(j-1>=0&&a[i+1][j-1]=='v'&&a[i+1][j+1]=='v')
                    ++cnt,a[i+1][j-1]='0',a[i+1][j+1]='0';
                else if(j+2<m&&a[i][j+2]=='^'&&a[i+1][j+1]=='v')
                    ++cnt,a[i][j+2]='0',a[i+1][j+1]='0';
            }
    return cnt;
}

int solve2()
{
    int cnt=0;
    for(int i=0;i<n-2;++i)
        for(int j=0;j<m;++j)
            if(a[i][j]=='<')
            {
                if(i+2<n&&j<m-1&&a[i+1][j+1]=='>'&&a[i+2][j]=='<')
                    ++cnt,a[i+1][j+1]='0',a[i+2][j]='0';
            }

            else if(a[i][j]=='>')
            {
                if(i+2<n&&a[i+1][j-1]=='<'&&a[i+2][j]=='>')
                    ++cnt,a[i+1][j-1]='0',a[i+2][j]='0';
            }
    return cnt;

}

int main()
{
   while(~scanf("%d%d",&n,&m))
   {
       for(int i=0;i<n;++i)
            scanf("%s",a[i]);

//for(int i=0;i<n;++i)
// printf("%s",a[i]),putchar('\n');
        int ans1=solve1();
        int ans2=solve2();
//cout<<ans1<<" "<<ans2<<endl;
        int ans=ans1+ans2;
        printf("%d\n",ans);

   }
}

/*
2 4
^^^^
>vv<
2 4
vvvv
>^^<
4 2
v>
<>
<>
^>
3 4
^>^>
<v>v
>>>>
2 9
^<^<^<^<^
<v<v<v<v<

2
0
2
2
3
*/

猜你喜欢

转载自blog.csdn.net/wangqianqianya/article/details/82531111
今日推荐