1. 程式人生 > 實用技巧 >Makefile的介紹與使用(二)

Makefile的介紹與使用(二)

題目地址:acwing

題目大意:

你是一個可以控制風的神仙。

通過把雲吹到不同的位置,你可以控制降雨。

雲下地區會降雨,沒有云的地方陽光燦爛。

你是一個仁慈的神,希望土地在平時可以有足夠的雨水,在趕集和過節能夠充滿陽光。

你負責掌控一個村子的天氣狀況。

這個村子呈4 x 4的網格狀分佈,村子內的每個區域被編號如下圖所示:

你擁有一片2 x 2大小的雲,這片雲不能到村子以外的地方。

你將獲得一段時間內村子每個區域的趕集和過節時間表。

在這段時間的第一天,中部地區(6-7-10-11)將會下雨。

在接下來的每一天中,您可以在四個基本方向(東南西北)之中選取一個方向,將雲移動1或2個方格,或將其保持在相同位置。

不允許對角線移動,所有動作都在一天開始時發生。

任何地區都不能連續七天或以上時間都不降雨。

這段時間以外的日子的下雨狀況你無需做任何考慮。

題目思路:暴力搜尋+記憶化

要注意的地方就是如何能判斷一個地方是否有7天連續不下雨,但是通過分析我們可以得出四個角下雨一定能夠保證所在的四方格里的村莊都下雨,所以我們只需要判斷四個角是不是連續7天不下雨就行了,反證法就是隻要四個角七天內下雨那麼一定能保證所有的村莊連續不下雨的天數都不會超過7天

程式碼如下(看了yxc的題解視訊):

#include <iostream>
#include <cstring>
#include <queue>
using
namespace std; const int N = 366; int st[N][4][4]; int f[N][3][3][7][7][7][7]; struct node{ int day,x,y,s1,s2,s3,s4; }; int dx[5]={-1,0,1,0,0}; int dy[5]={0,1,0,-1,0}; int n; int bfs(){ memset(f,0,sizeof f); if(st[1][1][1]||st[1][1][2]||st[1][2][1]||st[1][2][2])return 0; f[1][1][1][1][1][1][1
]=1; queue<node> q; q.push({1,1,1,1,1,1,1}); while(q.size()){ auto t=q.front(); q.pop(); if(t.day==n)return 1; for(int i=0;i<5;i++){ for(int j=1;j<=2;j++){ int s1=t.s1,s2=t.s2,s3=t.s3,s4=t.s4; int nx=t.x+dx[i]*j,ny=t.y+dy[i]*j; if(nx<0||nx>2||ny<0||ny>2)continue; auto& sti=st[t.day+1]; if(sti[nx][ny]||sti[nx+1][ny]||sti[nx][ny+1]||sti[nx+1][ny+1])continue; if(nx==0&&ny==0){ s1=0; } else if(++s1==7)continue; if(nx==0&&ny==2){ s2=0; } else if(++s2==7)continue; if(nx==2&&ny==0){ s3=0; } else if(++s3==7)continue; if(nx==2&&ny==2){ s4=0; } else if(++s4==7)continue; if(f[t.day+1][nx][ny][s1][s2][s3][s4])continue; f[t.day+1][nx][ny][s1][s2][s3][s4]=1; q.push({t.day+1,nx,ny,s1,s2,s3,s4}); } } } return 0; } int main(){ while(cin>>n&&n){ for(int i=1;i<=n;i++){ for(int j=0;j<4;j++){ for(int k=0;k<4;k++){ cin>>st[i][j][k]; } } } cout<<bfs()<<endl; } }

思路並不難,就是要減去一些無效狀態和記憶化的狀態,(也可以用dfs寫,dp寫)