【POJ3740】Easy Finding,解題報告+思路+代碼

來源:互聯網
上載者:User
#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>//#define INPUT/**    Problem: poj3740 - Easy Finding    Begin Time:8:30 p.m. 20th/Mar/2012    End Time: 8:42 p.m. 21st/Mar/2012    Last Time: Maybe 4hours-;    Input:    Standard output:    Knowledge point:    DFS+回溯+剪枝    State: WA x 1 , TLE x 1  -> AC    Thought:    --------------------AC後的總結----------------------    1.定義一個數組selectedCol,表示目前選出了幾列中有"1".    2.在choose之前,要檢查selectedRow[i]是否為true.      如果是true,這行就選過了,就continue    3.在每次choose某行的時候,都在choose函數裡進行check    if choose_row[i]  == 1 && selectedCol[i] == 1 return false;    if choose_row[i] && !selectedCol[i] => selectedCol[i] = 1;    但是在choose之前記得儲存selectedCol的狀態,以便return false之前進行回溯。    4.如果choose失敗的話,就要檢查是否已經找到了全1,如果找到了        isFound = true;        在遞迴函式裡檢查isFound = true的話就return true;    5.如果沒找到的話,記得回溯。這就要求在遞迴函式裡每次儲存selectedCol的狀態,失敗了進行回溯。    6.如果leftRow == 0 ,那麼就check,如果check,return true;,否則return false;    剪枝策略:        每層遞迴都是從 i = 0 to rowNum 開始選        如果上層遞迴選了i,那就下層遞迴從i+1開始選。        因為上層遞迴從0開始選,選到i的話[0,i]的情況已經由上層遞迴選完了。        而且行數跟順序無關        比如說        第一層遞迴選了1        那麼第二,第三……一直到最後一層遞迴,肯定是把第一次選1的所有情況都遍曆了,        第一層遞迴才能去選2        而且        1   2   3   4   5   6        和        6   5   4   3   2   1        這麼選擇是沒有區別的,所以下一層遞迴從ind+1開始就可以了        加上這個剪枝,653ms就過了。    更變態的思路:        由於是0,1我們可以按位表示嘛!然後按照規則算,應該會非常快~    遞迴函式定義:    f(int totalRow,int totalCol,int leftRow,int ind);    totalRow表示總共有多少行    totalCol表示列數    leftRow表示還有幾行沒選    int ind表示從現在第幾行開始選。    --------------------AC前的塗鴉----------------------    其實這道題跟STICK是差不多的,當然,狀態壓縮是必須的。    每行壓縮成一個數字,然後是否有幾個數字相加起來正好等於    1111111....    注意,最多可以有10^300,所以這個比較囧!    每一個狀態就是按行i是否被選擇來決定,    選擇了某一行之後,就定義tmp[m]對應的列已經被佔領。    那麼剩下的就轉化為用leftNum - 1行來拼出來其他的列了,如果都能拼出來,那麼    return true,否則return false;    定義函數f(rowNum,colNum,leftNum);表示總共有rowNum列,有colNum行,剩leftNum沒有選    每次選擇的時候定義一個check,看看是否已經選出了每列全有1的行。    還有一個check2,看看當前選的行是否跟以前的行有衝突。**/using namespace std;int matrix[20][310]; ///開大一點總是沒錯的bool selectedCol[310];bool selectedRow[18];bool isFound;bool checked(const int colNum){    for(int i = 0 ; i < colNum ; i++)    {        if (!selectedCol[i])            return false;    }    return true;}bool choose(const int a[310],int colNum){    int tmp_state[310];    memset(tmp_state,0,sizeof(tmp_state));    memcpy(tmp_state,selectedCol,sizeof(tmp_state));    for(int i = 0 ; i < colNum ; i++)    {        if(!selectedCol[i] && a[i] )        {            selectedCol[i] = a[i];        }        else        {            if ( selectedCol[i] && a[i] )            {                memcpy(selectedCol,tmp_state,sizeof(tmp_state));                return false;            }        }    }    return true;}bool Solve(int rowNum,int colNum,int leftNum,int ind){    int tmp_state[310];    memset(tmp_state,0,sizeof(tmp_state));    if( isFound )        return true;    if (leftNum == 0)    {        if ( checked(colNum) )        {            isFound = true;            return true;        }        else        {            return false;        }    }    for(int i = ind ; i < rowNum ; i++)    {        memcpy(tmp_state,selectedCol,sizeof(tmp_state));        if( isFound ) return true;        if ( selectedRow[i] ) continue;        if ( choose(matrix[i],colNum) )        {            if( selectedRow[i] != true && !checked(colNum) )            {                selectedRow[i] = true;                Solve(rowNum,colNum,leftNum - 1,i+1);            }            else            {                if ( checked(colNum) )                {                 isFound = true;                 return true;                }            }       //     memcpy(matrix[i],tmp_state,sizeof(tmp_state));            memcpy(selectedCol,tmp_state,sizeof(selectedCol));            selectedRow[i] = false;        }      //  selectedRow[i] = false;    }    return false;}int main(){    int n,m;#ifdef INPUT    freopen("b:\\acm\\poj3740\\input.txt","r",stdin);#endif    while(scanf("%d%d",&m,&n) != EOF )    {        isFound = false;        memset(matrix,0,sizeof(matrix));        memset(selectedCol,0,sizeof(selectedCol));        memset(selectedRow,0,sizeof(selectedRow));        for(int i = 0 ; i < m ; i++)        {            for(int j = 0 ; j < n ; j++)            {                scanf("%d",&matrix[i][j]);            }        }        if ( Solve(m,n,m,0) )        {            printf("Yes, I found it\n");        }        else        {            printf("It is impossible\n");        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.