AtCoder Grand Contest 043--A - Range Flip Find Route

Posted by samirk on Sun, 22 Mar 2020 16:00:03 +0100

A - Range Flip Find Route

Meaning: this question is to give you a matrix to find the least number of black squares from (1, 1) to (h, w)

Problem solving: when I was doing this problem, what I thought of at first was to use DFS to find out every possible way and compare their minimum values. As a result, after the game, I learned that DP can also be used: Here we define a two-dimensional array dp[h][w], Among them, dp[i][j] represents the minimum number of black blocks at the point of arrival (I, j), and it also represents that this block does not need to be turned over (Title Description, the black block needs to be turned over into a white block). Each time, the minimum value can be calculated.

Here is the code for TLE:

#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int min_n=100*100+5;
int sum=0;//Store temporary answers 
int h,w;
char ptr[150][150];
int net[2][2]={{0,1},{1,0}}; 
bool check(int x,int y){
    return (x<=h/*That's ok*/)&&(y<=w/*column*/);//Legal judgement 
} 
void dfs(int x,int y){//Traverse all, find the minimum number of operands 
    if(x==h&&y==w){//The end of this time 
        min_n=min(min_n,sum);//Take out the minimum value
        return ;//End this call 
    }
    //Looking for the next step
    for(int i=0;i<2;i++){
        int nx=x+net[i][0];
        int ny=y+net[i][1];//Find next action
        //Judge whether the next operation is legal
        if(check(nx,ny)){//If lawful
            if(ptr[nx][ny]=='#'){//Determine whether the next position is black or white. If it is black, add an operation 
                sum++;
            }
            dfs(nx,ny);
            if(ptr[nx][ny]=='#'){
                sum--;
            } 
        } 
    }
}
int main(){
    cin>>h>>w;
    for(int i=1;i<=h;i++){
        for(int j=1;j<=w;j++){
            cin>>ptr[i][j];
        }
    }//After data input, start to process data
    //First, we need to judge whether the first one is right or not
    if(ptr[1][1]=='#'){
        sum++;//Counter plus one operation 
    } 
    dfs(1,1);//And then go through the search from the beginning 
    cout<<min_n<<endl;
    return 0;
}

Here is the code for AC:

#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int min_n=100*100+5;
int sum=0;//Store temporary answers 
int h,w;
char ptr[150][150];
int net[2][2]={{0,1},{1,0}}; 
bool check(int x,int y){
    return (x<=h/*That's ok*/)&&(y<=w/*column*/);//Legal judgement 
} 
void dfs(int x,int y){//Traverse all, find the minimum number of operands 
    if(x==h&&y==w){//The end of this time 
        min_n=min(min_n,sum);//Take out the minimum value
        return ;//End this call 
    }
    //Looking for the next step
    for(int i=0;i<2;i++){
        int nx=x+net[i][0];
        int ny=y+net[i][1];//Find next action
        //Judge whether the next operation is legal
        if(check(nx,ny)){//If lawful
            if(ptr[nx][ny]=='#'){//Determine whether the next position is black or white. If it is black, add an operation 
                sum++;
            }
            dfs(nx,ny);
            if(ptr[nx][ny]=='#'){
                sum--;
            } 
        } 
    }
}
int main(){
    cin>>h>>w;
    for(int i=1;i<=h;i++){
        for(int j=1;j<=w;j++){
            cin>>ptr[i][j];
        }
    }//After data input, start to process data
    //First, we need to judge whether the first one is right or not
    if(ptr[1][1]=='#'){
        sum++;//Counter plus one operation 
    } 
    dfs(1,1);//And then go through the search from the beginning 
    cout<<min_n<<endl;
    return 0;
}

Topics: C++