1. 程式人生 > >5.20 考試 20 未完

5.20 考試 20 未完

ont turn 存在 class 平原 全部 ron for else

水災(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>
 2
#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 }
View Code

正解(還未看):

技術分享
 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 未完