Round #3
題源:感謝 by hzwer
水災(sliker.cpp/c/pas) 1000MS 64MB
大雨應經下了幾天雨,卻還是沒有停的樣子。土豪CCY剛從外地賺完1e元回來,知道不久除了自己別墅,其他的地方都將會被洪水淹沒。
CCY所在的城市可以用一個N*M(N,M<=50)的地圖表示,地圖上有五種符號:“. * X D S”。其中“X”表示石頭,水和人都不能從上面經過。“.”表示平原,CCY和洪水都可以經過。“*”表示洪水開始地方(可能有多個地方開始發生洪水)。“D”表示CCY的別墅。“S”表示CCY現在的位置。
CCY每分鐘可以向相鄰位置移動,而洪水將會在CCY移動之后把相鄰的沒有的土地淹沒(從已淹沒的土地)。
求CCY回到別墅的最少時間。如果聰哥回不了家,就很可能會被淹死,那么他就要膜拜黃金大神漲RP來呼叫直升飛機,所以輸出“ORZ hzwer!!!”。
輸入文件 sliker.in
輸出文件 sliker.out
Input
3 3
D.*
…
.S.
Output
3
Input
3 3
D.*
.....S
Output
ORZ hzwer!!!
Input
3 6
D...*.
.X.X..
....S.
Output
6
最短路問題,而且也是經典的BFS題目,但是增加了一個限制”洪水“,而洪水的影響則是在t時刻之后淹沒位置(x,y),而我要路過這個位置,則要在t時刻之前路過;
那么可以這樣解決,先BFS求出洪水淹沒(x,y)所需要的時間t,再BFS求我能否從起始點抵達城堡,對于每抵達的一個點(x,y)要符合幾個條件:
1.不能是石頭”X“
2.不能超過邊界,即1<=x<=n&&1<=y<=m
3.當前時刻這地方還沒被洪水淹沒,即我抵達的時間T<=t(洪水淹沒(x,y)的時間)
那么這題就很愉快的解決了,以下是代碼:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<stack> #include<queue> #include<map> #include<set> #include<cmath> #include<utility> #include<numeric> #include<iterator> #include<algorithm> #include<functional> #include<ctime> #include<cassert> using std::cin; using std::cout; using std::endl; typedef long long ll; typedef unsigned long long ull; typedef std::pair<int,int> P; #define FOR(i,init,len) for(int i=(init);i<(len);++i) #define For(i,init,len) for(int i=(init);i<=(len);++i) #define fi first #define se second #define pb push_back #define is insert namespace IO { inline char getchar() { static const int BUFSIZE=5201314; static char buf[BUFSIZE],*begin,*end; if(begin==end) { begin=buf; end=buf+fread(buf,1,BUFSIZE,stdin); if(begin==end) return -1; } return *begin++; } } inline void read(int &in) { int c,symbol=1; while(isspace(c=IO::getchar())); if(c=='-') { in=0;symbol=-1; } else in=c-'0'; while(isdigit(c=IO::getchar())) { in*=10;in+=c-'0'; } in*=symbol; } inline int read() { static int x;read(x);return x; } ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; } ll lcm(ll a,ll b) { return a/gcd(a,b)*b; } #define PA(name,init,len) cout<<#name"["<<(len-init)<<"]=";FOR(_,init,len) cout<<name[_]<<" \n"[_==(len-1)]; #define Pa(name,init,len) cout<<#name"["<<(len-init+1)<<"]=";For(_,init,len) cout<<name[_]<<" \n"[_==(len)]; #define PV(name) cout<<#name"="<<name<<'\n'; const int maxn=55; int n,m; int dist[maxn][maxn]; bool vis[maxn][maxn]; char s[maxn][maxn]; const int dx[]={0,1,0,-1}; const int dy[]={1,0,-1,0}; struct Node{ int x,y,time; Node(int x=0,int y=0,int time=0):x(x),y(y),time(time){} }; //主要檢查坐標是否越界和是否來過 inline bool check(int x,int y){return x>=1&&x<=n&&y>=1&&y<=m&&!vis[x][y];} //bfs求洪水在什么時候淹沒(x,y),那么我必須在洪水淹沒之前抵達這里,否則我將不能抵達這里 void flood_bfs(){ std::queue<Node> q; For(i,1,n) For(j,1,m) if(s[i][j]=='*') q.push(Node(i,j,0)),vis[i][j]=true; memset(dist,0x3f,sizeof(dist));//初始距離賦值為最大值,按字節賦值0x3f,結果為dist[i][j]=0x3f3f3f3f=1061109567 while(!q.empty()){ Node t=q.front();q.pop(); dist[t.x][t.y]=t.time; FOR(i,0,4){ int x=t.x+dx[i],y=t.y+dy[i]; if(check(x,y)&&s[x][y]!='X'&&s[x][y]!='D') q.push(Node(x,y,t.time+1)),vis[x][y]=true; } } } //bfs求我抵達城堡的最短時間,如果不能抵達,返回-1 int bfs(){ std::queue<Node> q; memset(vis,0,sizeof(vis)); For(i,1,n) For(j,1,m) if(s[i][j]=='S') q.push(Node(i,j,0)),vis[i][j]=true; while(!q.empty()){ Node t=q.front();q.pop(); if(s[t.x][t.y]=='D') return t.time; FOR(i,0,4){ int x=t.x+dx[i],y=t.y+dy[i]; if(check(x,y)&&s[x][y]!='X'&&t.time+1<dist[x][y]) q.push(Node(x,y,t.time+1)),vis[x][y]=true; } } return -1; } int main() { #ifdef MengLan int Beginning=clock(); //freopen("in","r",stdin); //freopen("out","w",stdout); #endif // MengLan scanf("%d%d",&n,&m); For(i,1,n) scanf("%s",s[i]+1); flood_bfs(); int ans=bfs(); if(ans==-1) puts("ORZ hzwer!!!"); else printf("%d\n",ans); #ifdef MengLan printf("Time: %d\n",clock()-Beginning); system("pause"); #endif // MengLan return 0; }
某種數列問題 (jx.cpp/c/pas) 1000MS 256MB
眾所周知,chenzeyu97有無數的妹子(阿掉!>_<),而且他還有很多惡趣味的問題,繼上次糾結于一排妹子的排法以后,今天他有非(chi)常(bao)認(cheng)真(zhe)去研究一個奇怪的問題。有一堆他的妹子站成一排,然后對于每個妹子有一個美麗度,當然美麗度越大越好,chenzeyu97妹子很多,但是質量上不容樂觀,經常出現很多美麗度為負數的妹子(喜聞樂見),chenzeyu97希望從一排妹子里找出3隊連續的妹子,使她們的美麗度和最大。注意,一個妹子不能被編入多個隊伍而且一定要拿出三隊,不然czy會閑著沒事做~。
簡單滴說就是:
給定一個數列,從中找到3個無交集的連續子數列使其和最大。
【輸入文件】
第一行一個數n,表示數列長度。
接下來有n行,每行一個數,第i行為第i個數。
【輸出文件】
僅有一個數,表示最大和。
【樣例輸入】 jx.in
10
-1
2
3
-4
0
1
-6
-1
1
-2
【樣例輸出】 jx.out
7
【樣例說明】
第一隊妹子取2,3。
第二隊妹子取0,1。
第三隊妹子取1。
【數據范圍】
請大家放心,雖然chenzeyu97妹子無數,但是這次他叫來的個數n是有限的。=v=
對于30%的數據,妹子數不大于200。
對于60%的數據,妹子數不大于2000。
對于100%的數據,妹子數1000000。
而且,由于chenzeyu97沒有CCR那樣的影響力,所以他的妹子選完的最大美麗度和不超過maxlongint。(注:CCR隨便選就爆long long,因為他是把妹狂魔=V=)。
兩種解法???第一種,求最大連續和,
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<stack> #include<queue> #include<map> #include<set> #include<cmath> #include<utility> #include<numeric> #include<iterator> #include<algorithm> #include<functional> #include<ctime> #include<cassert> using std::cin; using std::cout; using std::endl; typedef long long ll; typedef unsigned long long ull; typedef std::pair<int,int> P; #define FOR(i,init,len) for(int i=(init);i<(len);++i) #define For(i,init,len) for(int i=(init);i<=(len);++i) #define fi first #define se second #define pb push_back #define is insert namespace IO { inline char getchar() { static const int BUFSIZE=5201314; static char buf[BUFSIZE],*begin,*end; if(begin==end) { begin=buf; end=buf+fread(buf,1,BUFSIZE,stdin); if(begin==end) return -1; } return *begin++; } } inline void read(int &in) { int c,symbol=1; while(isspace(c=IO::getchar())); if(c=='-') { in=0;symbol=-1; } else in=c-'0'; while(isdigit(c=IO::getchar())) { in*=10;in+=c-'0'; } in*=symbol; } inline int read() { static int x;read(x);return x; } ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; } ll lcm(ll a,ll b) { return a/gcd(a,b)*b; } #define PA(name,init,len) cout<<#name"["<<(len-init)<<"]=";FOR(_,init,len) cout<<name[_]<<" \n"[_==(len-1)]; #define Pa(name,init,len) cout<<#name"["<<(len-init+1)<<"]=";For(_,init,len) cout<<name[_]<<" \n"[_==(len)]; #define PV(name) cout<<#name"="<<name<<'\n'; const int maxn=1e6+10; int in[maxn]; ll d[4][maxn][2]; int n; int main() { #ifdef MengLan int Beginning=clock(); //freopen("in","r",stdin); //freopen("out","w",stdout); #endif // MengLan scanf("%d",&n); For(i,1,n) scanf("%d",in+i); For(i,1,3) For(j,1,n){ d[i][j][0]=std::max({d[i-1][j-1][0],d[i-1][j-1][1],d[i][j-1][0]}); d[i][j][1]=std::max(d[i][j-1][1],d[i][j-1][0])+in[j]; //printf("d[%d][%d][0]=%lld d[%d][%d][1]=%lld\n",i,j,d[i][j][0],i,j,d[i][j][1]); } ll ans=-1e18; For(i,3,n) ans=std::max(ans,d[3][i][1]); printf("%lld\n",ans); #ifdef MengLan printf("Time: %d\n",clock()-Beginning); system("pause"); #endif // MengLan return 0; }
浙公網安備 33010602011771號