5.20 考試 20 未完
水災(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
解題思路:對於每一秒,洪水東會移動,是較難處理的,可以用一個三維數組記錄每一秒時洪水的狀態f[s][i][j],第s秒時洪水的狀態;然後就是bfs
由於當時先做的後兩題,so此題時間不夠,亂寫一通:
當時代碼,留個紀念
1 #include<iostream> 2View Code#include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 6 using namespace std; 7 const int N=60; 8 9 int a[N][N]; 10 11 inline void read(int &x) 12 { 13 char c=getchar(); 14 x=0; 15 while(c<‘0‘||c>‘9‘)c=getchar(); 16 while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar(); 17 } 18 19 int sx,sy,dx,dy,xx,xy; 20 21 int main() 22 { 23 freopen("sliker.in","r",stdin); 24 freopen("sliker.out","w",stdout); 25 int n,m; 26 read(n); 27 read(m); 28 char c; 29 for(int i=1;i<=n;i++) 30 for(int j=1;j<=m;j++) 31 { 32 scanf("%c",&c); 33 if(c==‘S‘) 34 sx=i,sy=j; 35 if(c==‘*‘) 36 xx=i,xy=j; 37 if(c==‘D‘) 38 dx=i,dy=j; 39 } 40 if(((dx<=xx&&dx<=sx)||(dx>=xx&&dx>=sx))&&((dy<=xy&&dy>=sy)||(dy>=xy&&dy<=sy))) 41 { 42 int xj=abs(xx-dx)-1+abs(xy-dy)+3; 43 int sj=abs(sx-dx)+abs(xy-dy); 44 if(sj<=xj) {printf("%d",sj); return 0;} 45 else {printf("ORZ hzwer!!!"); return 0;} 46 } 47 if(((dx<=xx&&dx<=sx)||(dx>=xx&&dx>=sx))&&((dy<=xy&&dy<=sy)||(dy>=xy&&dy>=sy))) 48 { 49 if(sy<=xy) {printf("%d",abs(sx-dx)+abs(sy-dy));return 0;} 50 else {printf("ORZ hzwer!!!");return 0;} 51 } 52 if(((dx<=xx&&dx>=sx)||(dx>=xx&&dx<=sx))&&((dy<=xy&&dy>=sy)||(dy>=xy&&dy<=sy))) 53 { 54 int xj=abs(xx-dx)+abs(xy-dy); 55 int sj=abs(sx-dx)+abs(xy-dy); 56 if(sj<=xj) {printf("%d",sj); return 0;} 57 else {printf("ORZ hzwer!!!");return 0;} 58 } 59 if(((dx<=xx&&dx>=sx)||(dx>=xx&&dx<=sx))&&((dy<=xy&&dy<=sy)||(dy>=xy&&dy>=sy))) 60 { 61 int xj=abs(xx-dx)+abs(xy-dy); 62 int sj=abs(sx-dx)+abs(sy-dy); 63 if(sj<=xj) {printf("%d",sj);return 0;} 64 else {printf("ORZ hzwer!!!");return 0;} 65 } 66 printf("ORZ hzwer!!!"); 67 return 0; 68 }
正解(還未看):
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 const int N=55; 6 char a[N][N]; 7 bool vis[N][N]; 8 int n,m,ex,ey,d[N][N],dis[N][N]; 9 struct node{ 10 int x,y; 11 node(int x=0,int y=0):x(x),y(y){} 12 }; 13 const int dx[]={0,0,1,-1}; 14 const int dy[]={1,-1,0,0}; 15 inline bool inside(int &x,int &y){ 16 return x>0&&x<=n&&y>0&&y<=m; 17 } 18 void bfs(int sx,int sy){ 19 memset(vis,0,sizeof vis); 20 queue<node>q; 21 q.push(node(sx,sy)); 22 vis[sx][sy]=1; 23 d[sx][sy]=0; 24 while(!q.empty()){ 25 node h=q.front();q.pop(); 26 int px=h.x,py=h.y; 27 vis[px][py]=0; 28 for(int i=0,nx,ny;i<4;i++){ 29 nx=px+dx[i]; 30 ny=py+dy[i]; 31 if(inside(nx,ny)&&a[nx][ny]!=‘X‘&&a[nx][ny]!=‘D‘){ 32 if(d[nx][ny]>d[px][py]+1){ 33 d[nx][ny]=d[px][py]+1; 34 if(!vis[nx][ny]){ 35 vis[nx][ny]=1; 36 q.push(node(nx,ny)); 37 } 38 } 39 } 40 } 41 } 42 } 43 void spfa(int sx,int sy){ 44 memset(vis,0,sizeof vis); 45 queue<node>q; 46 q.push(node(sx,sy)); 47 vis[sx][sy]=1; 48 dis[sx][sy]=0; 49 while(!q.empty()){ 50 node h=q.front();q.pop(); 51 int px=h.x,py=h.y; 52 vis[px][py]=0; 53 for(int i=0,nx,ny;i<4;i++){ 54 nx=px+dx[i]; 55 ny=py+dy[i]; 56 if(inside(nx,ny)&&a[nx][ny]!=‘X‘){ 57 if(dis[px][py]+1>=d[nx][ny]) continue; 58 if(dis[nx][ny]>dis[px][py]+1){ 59 dis[nx][ny]=dis[px][py]+1; 60 if(!vis[nx][ny]){ 61 vis[nx][ny]=1; 62 q.push(node(nx,ny)); 63 } 64 } 65 } 66 } 67 } 68 } 69 int main(){ 70 memset(dis,0x3f3f3f3f,sizeof dis); 71 memset(d,0x3f3f3f3f,sizeof d); 72 scanf("%d%d",&n,&m); 73 for(int i=1;i<=n;i++){ 74 scanf("%s",a[i]+1); 75 } 76 for(int i=1;i<=n;i++){ 77 for(int j=1;j<=m;j++){ 78 if(a[i][j]==‘*‘){ 79 bfs(i,j); 80 } 81 } 82 } 83 for(int i=1;i<=n;i++){ 84 for(int j=1;j<=m;j++){ 85 if(a[i][j]==‘S‘){ 86 spfa(i,j); 87 } 88 if(a[i][j]==‘D‘){ 89 ex=i;ey=j; 90 } 91 } 92 } 93 if(dis[ex][ey]<0x3f3f3f3f) printf("%d\n",dis[ex][ey]); 94 else puts("ORZ hzwer!!!"); 95 return 0; 96 }View Code
某種數列問題 (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=)。
解題思路:這是一道我感覺較難的dp問題,對於每一個元素,都存在選與不選的問題,所以定義 f[i][j][0]表示前 i 個中取 j 段的最大值,
其中第 i 個被取到。f[i][j][1]表示前i個中取j段的最大值,
其中第 i 個沒被取到。顯然max(f[n][3][0],f[n][3][1])即是所求,不過當時寫了個暴力,感覺不應該只得20分的,可能有錯誤吧
暴力20:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 6 using namespace std; 7 const int N=1000010; 8 9 int a[N]; 10 int b[N-30]; 11 int js; 12 int n; 13 14 inline void read(int &x) 15 { 16 char c=getchar(); 17 x=0; 18 while(c<‘0‘||c>‘9‘)c=getchar(); 19 while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar(); 20 } 21 22 int main() 23 { 24 freopen("jx.in","r",stdin); 25 freopen("jx.out","w",stdout); 26 read(n); 27 for(int i=1;i<=n;i++) 28 { 29 scanf("%d",&a[i]); 30 } 31 int ans; 32 for(int i=1;i<=n;i++) 33 { 34 if(a[i]>=0) 35 { 36 ans=0; 37 int j=i; 38 while(a[j]>=0) 39 { 40 ans+=a[j]; 41 j++; 42 } 43 b[++js]=ans; 44 i=j; 45 } 46 } 47 sort(b+1,b+js+1); 48 long long Answer=b[js]+b[js-1]+b[js-2]; 49 50 printf("%lld",Answer); 51 52 return 0; 53 } 54 /* 55 10 56 -1 57 2 58 3 59 -4 60 0 61 1 62 -6 63 -1 64 1 65 -2 66 */View Code
正解:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 5 #define maxn 1000001 6 7 using namespace std; 8 9 inline int read() 10 { 11 int x=0,f=1; 12 char ch=getchar(); 13 while(ch<‘0‘||ch>‘9‘) 14 { 15 if(ch==‘-‘)f=-1; 16 ch=getchar(); 17 } 18 while(ch>=‘0‘&&ch<=‘9‘) 19 { 20 x*=10; 21 x+=ch-‘0‘; 22 ch=getchar(); 23 } 24 return x*f; 25 } 26 27 int n,cnt; 28 int a[maxn]; 29 int s[maxn]; 30 int f[maxn][4][2]; 31 32 /* 33 34 dp f[i][j][0]表示前i個中取j段的最大值, 35 其中第i個被取到。f[i][j][1]表示前i個中取j段的最大值, 36 其中第i個沒被取到。顯然max(f[n][3][0],f[n][3][1])即是所求 37 38 */ 39 40 int main() 41 { 42 //freopen("jx.in","r",stdin); 43 //freopen("jx.out","w",stdout); 44 n=read(); 45 for (int i=1; i<=n; i++) a[i]=read(); 46 for (int i=1; i<=n; i++) 47 for (int j=1; j<=3; j++) 48 { 49 f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]); 50 f[i][j][1]=max(f[i][j][1],f[i-1][j-1][0]+a[i]); 51 f[i][j][1]=max(f[i][j][1],f[i-1][j][1]+a[i]); 52 } 53 printf("%d",max(f[n][3][1],f[n][3][0])); 54 }View Code
密碼鎖 1000MS 512MB
Input: password.in
Output: password.out
【題目描述】
hzwer有一把密碼鎖,由N個開關組成。一開始的時候,所有開關都是關上的。當且僅當開關x1,x2,x3,...xk為開,其他開關為關時,密碼鎖才會打開。
他可以進行M種的操作,每種操作有一個size[i],表示,假如他選擇了第i種的操作的話,他可以任意選擇連續的size[i]個格子,把它們全部取反。(註意,由於黃金大神非常的神,所以操作次數可以無限>_<)
本來這是一個無關緊要的問題,但是,黃金大神不小心他的錢丟進去了,沒有的錢他哪裏能逃過被chenzeyu97 NTR的命運?>_< 於是,他為了虐爆czy,也為了去泡更多的妹子,決定打開這把鎖。但是他那麽神的人根本不屑這種”水題”。於是,他找到了你。
你的任務很簡單,求出最少需要多少步才能打開密碼鎖,或者如果無解的話,請輸出-1。
【輸入格式】
第1行,三個正整數N,K,M,如題目所述。
第2行,K個正整數,表示開關x1,x2,x3..xk必須為開,保證x兩兩不同。
第三行,M個正整數,表示size[i],size[]可能有重復元素。
【輸出格式】
輸出答案,無解輸出-1。
【樣例輸入1】
10 8 2
1 2 3 5 6 7 8 9
3 5
Size[1] size[2]
【樣例輸出1】
2
【樣例輸入2】
3 2 1
1 2
3
【樣例輸出2】
-1
【數據規模】
對於50%的數據,1≤N≤20,1≤k≤5,1≤m≤3;
對於另外20%的數據,1≤N≤10000,1≤k≤5,1≤m≤30;
對於100%的數據,1≤N≤10000,1≤k≤10,1≤m≤100。
解題思路:暴力感覺也能點分,不過0
當時:
思路:記錄出所有段的長度,存到struct 之後枚舉暴力,判斷每一段是否都能找到其整數倍,若不能輸出‘-1’,否則輸出最少步數,然而輸出-1,就得10分,可我卻得0分:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 6 using namespace std; 7 const int M=101; 8 const int N=10010; 9 const int K=15; 10 11 inline void read(int &x) 12 { 13 char c=getchar(); 14 x=0; 15 while(c<‘0‘||c>‘9‘)c=getchar(); 16 while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar(); 17 } 18 19 struct node{ 20 int js; 21 int start; 22 }E[M]; 23 24 int now; 25 int n,m,k; 26 int a[N]; 27 int b[K]; 28 bool vis[M]; 29 30 int main() 31 { 32 freopen("password.in","r",stdin); 33 freopen("password.out","w",stdout); 34 read(n);read(m);read(k); 35 read(a[1]); 36 E[1].js++; 37 E[1].start=a[1]; 38 now=1; 39 for(int i=2;i<=m;i++) 40 { 41 read(a[i]); 42 if(a[i]!=a[i-1]+1) 43 { 44 now++; 45 E[now].js++; 46 E[now].start=a[i]; 47 } 48 else E[now].js++; 49 } 50 for(int i=1;i<=k;i++) 51 { 52 read(b[i]); 53 } 54 for(int i=1;i<=now;i++) 55 { 56 if(!vis[E[i].js]) 57 { 58 vis[E[i].js]=1; 59 bool flag=0; 60 for(int j=1;j<=k&&!flag;j++) 61 { 62 if(b[j]==E[i].js) 63 { 64 flag=1; 65 } 66 } 67 if(!flag) { printf("-1"); return 0;} 68 } 69 } 70 printf("%d",now); 71 return 0; 72 }View Code
正解:
5.20 考試 20 未完