HDU1048 贪心+方格图

题目大意

约束
n*n的方格图,有的涂黑;每下一个格子,该格子十字方向不能再下;如果有被涂黑的格子隔开,在该格子十字内还是可以下
求解
最多可以下多少个格子

解题-贪心

贪心策略:选择影响其他格子最小的格子先下,下到不能下为止。
一个格子下下去,会影响其他格子——影响力
每个格子都有值=对其他格子的影响力(越小越先下,涂黑的/不能下的=INF最大值=不被考虑 tips最大值 影响力不会大于6
计算影响力:
影响力=影响的格子数=数十字内不碰涂黑的格子有几个

变量-伪代码

#define N 5
#define INF 0x3f3f3f3f
int chess[N] [N]
int value[N] [N]
int cnt,n

int cont 不能下的格子数(=n*n结束)

读入chess,cont=涂黑格子数;cnt=0;
根据chess初始化value()
{   
    chess涂黑的=INF;
    计算每一格的影响力(格子i,j)
    {
        向上/下/左/右遍历数格子
            当(没有遇到涂黑或者边界)
                value[i][j]++;
    }
}
当(cont<n*n)
    找value最小的格子
    cnt++;该格子=INF不能下;cont++;
    该格子影响的格子不能下(格子i,j)
    {
        向上/下/左/右遍历数格子
            当(没有遇到涂黑或者边界)
                没有被之前影响的格子=INF;cont++;
    }
打印cnt

AC代码

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#define LL long long
#define N 5 
#define IN 8
#define FOR(i) for(i=0;i<n;i++) 
using namespace std;
int chess[N][N];
int value[N][N]; 

int main(){
    ios::sync_with_stdio(false);
    int cnt,n;
    char x;
    int cont,i,j,k,m,m_i,m_j; 
    while(cin>>n&&n){
        cont=0;cnt=0;
        memset(chess,0,sizeof(chess));
        memset(value,0,sizeof(value));
        FOR(i){
            cin.get();
            FOR(j){
                cin.get(x);
                if(x=='X'){
                    chess[i][j]=1;
                    value[i][j]=IN;
                    cont++;
                }
            }
        }

        FOR(i) FOR(j){
            if(value[i][j]>6)continue;
            k=i+1;
            while(k<n&&!chess[k][j])
                value[i][j]++,k++;
            k=i-1;
            while(k>=0&&!chess[k][j])
                value[i][j]++,k--;
            k=j+1;
            while(k<n&&!chess[i][k])
                value[i][j]++,k++;
            k=j-1;
            while(k>=0&&!chess[i][k])
                value[i][j]++,k--;
        }
        while(cont<n*n){
            m=IN;
            FOR(i) FOR(j)
                if(m>value[i][j]){
                    m=value[i][j];
                    m_i=i;m_j=j;
                }   
            cnt++;value[m_i][m_j]=IN;cont++;
            k=m_i+1;
            while(k<n&&!chess[k][m_j]){
                if(value[k][m_j]<=6)
                    value[k][m_j]=IN,cont++;
                k++;
            }
            k=m_i-1;
            while(k>=0&&!chess[k][m_j]){
                if(value[k][m_j]<=6)
                    value[k][m_j]=IN,cont++;
                k--;
            }   
            k=m_j+1;
            while(k<n&&!chess[m_i][k]){
                if(value[m_i][k]<=6)
                    value[m_i][k]=IN,cont++;
                k++;
            }
            k=m_j-1;
            while(k>=0&&!chess[m_i][k]){
                if(value[m_i][k]<=6)
                    value[m_i][k]=IN,cont++;
                k--;
            }   
        }
        cout<<cnt<<endl;
    }
    return 0;
}

注意点

???
char x;
cin>>x;不是一个个字符读取的,是一串给的;
get();没有跳过\n
一个个字符读取:cin.get(char x)
get()读一个字符给char x ,其中‘ ’也读取,但是不读取’\n’

猜你喜欢

转载自blog.csdn.net/weixin_42946476/article/details/81607764