水灾(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
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #define maxn 60 6 using namespace std; 7 int n,m,ex,ey; 8 int d[maxn][maxn],dis[maxn][maxn],f[maxn][maxn]; 9 char a[maxn][maxn]; 10 int b[5]={0,0,1,0,-1}; 11 int c[5]={0,1,0,-1,0}; 12 queue<int>qx; 13 queue<int>qy; 14 void spfa(int x,int y) 15 { 16 int i,j,k; 17 memset(f,0,sizeof(f)); 18 d[x][y]=0; 19 qx.push(x); 20 qy.push(y); 21 f[x][y]=1; 22 while(!qx.empty()) 23 { 24 int nx=qx.front(); 25 int ny=qy.front(); 26 qx.pop(); 27 qy.pop(); 28 f[nx][ny]=0; 29 for(i=1;i<=4;i++) 30 { 31 int xx=nx+b[i]; 32 int yy=ny+c[i]; 33 if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&(a[xx][yy]!='X'&&a[xx][yy]!='D')) 34 { 35 if(d[xx][yy]>d[nx][ny]+1) 36 { 37 d[xx][yy]=d[nx][ny]+1; 38 if(!f[xx][yy]) 39 { 40 f[xx][yy]=1; 41 qx.push(xx); 42 qy.push(yy); 43 } 44 } 45 } 46 } 47 } 48 } 49 void SPFA(int x,int y) 50 { 51 int i,j,k; 52 memset(f,0,sizeof(f)); 53 dis[x][y]=0; 54 qx.push(x); 55 qy.push(y); 56 f[x][y]=1; 57 while(!qx.empty()) 58 { 59 int nx=qx.front(); 60 int ny=qy.front(); 61 qx.pop(); 62 qy.pop(); 63 f[nx][ny]=0; 64 for(i=1;i<=4;i++) 65 { 66 int xx=nx+b[i]; 67 int yy=ny+c[i]; 68 if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&(a[xx][yy]!='X')) 69 { 70 if(dis[nx][ny]+1>=d[xx][yy]) 71 continue; 72 if(dis[xx][yy]>dis[nx][ny]+1) 73 { 74 dis[xx][yy]=dis[nx][ny]+1; 75 if(!f[xx][yy]) 76 { 77 f[xx][yy]=1; 78 qx.push(xx); 79 qy.push(yy); 80 } 81 } 82 } 83 } 84 } 85 } 86 int main() 87 { 88 freopen("sliker.in","r",stdin); 89 freopen("sliker.out","w",stdout); 90 int i,j,k; 91 scanf("%d%d",&n,&m); 92 for(i=1;i<=n;i++) 93 scanf("%s",a[i]+1); 94 memset(d,127/3,sizeof(d)); 95 memset(dis,127/3,sizeof(dis)); 96 for(i=1;i<=n;i++) 97 { 98 for(j=1;j<=m;j++) 99 { 100 if(a[i][j]=='*') 101 spfa(i,j); 102 } 103 } 104 for(i=1;i<=n;i++) 105 { 106 for(j=1;j<=m;j++) 107 { 108 if(a[i][j]=='S') 109 SPFA(i,j); 110 if(a[i][j]=='D') 111 ex=i,ey=j; 112 } 113 } 114 if(dis[ex][ey]<dis[0][0]) printf("%d ",dis[ex][ey]); 115 else printf("ORZ hzwer!!! "); 116 return 0; 117 }
某种数列问题 (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=)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define maxn 1000010 5 using namespace std; 6 int n; 7 int a[maxn]; 8 int f[maxn][5][2]; 9 int init() 10 { 11 int x=0,f=1;char c=getchar(); 12 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 13 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 14 return x*f; 15 } 16 int main() 17 { 18 freopen("jx.in","r",stdin); 19 freopen("jx.out","w",stdout); 20 n=init(); 21 for(int i=1;i<=n;i++) 22 a[i]=init(); 23 memset(f,-127/3,sizeof(f)); 24 f[0][0][0]=0; 25 for(int i=1;i<=n;i++) 26 { 27 for(int j=0;j<=3;j++) 28 { 29 f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]); 30 if(j-1>=0)f[i][j][1]=max(f[i][j][1],f[i-1][j-1][0]+a[i]); 31 if(j-1>=0)f[i][j][1]=max(f[i][j][1],f[i-1][j-1][1]+a[i]); 32 f[i][j][1]=max(f[i][j][1],f[i-1][j][1]+a[i]); 33 } 34 } 35 int ans=max(f[n][3][0],f[n][3][1]); 36 printf("%d",ans); 37 return 0; 38 }
密码锁 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
【样例输出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。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 #define INF 0x7fffffff 8 using namespace std; 9 int n,m,k,sz; 10 long long f[1050000]; 11 int P[10010],bh[31],size[110]; 12 int dui[10010],dist[10010],d[31][31]; 13 bool mark[1050000]; 14 void bfs(int x) 15 { 16 int tou=1,wei=1,now,i; 17 memset(dist,-1,sizeof(dist)); 18 dui[1]=bh[x];dist[bh[x]]=0; 19 while(tou<=wei) 20 { 21 now=dui[tou];tou++; 22 for(i=1;i<=m;i++) 23 { 24 if(now-size[i]>0 && dist[now-size[i]]==-1) 25 { 26 dist[now-size[i]]=dist[now]+1; 27 dui[++wei]=now-size[i]; 28 } 29 if(now+size[i]<=n+1 && dist[now+size[i]]==-1) 30 { 31 dist[now+size[i]]=dist[now]+1; 32 dui[++wei]=now+size[i]; 33 } 34 } 35 } 36 for(i=1;i<=sz;i++) d[x][i]=dist[bh[i]]; 37 } 38 long long dp(int x) 39 { 40 if(!x) return 0; 41 if(mark[x]) return f[x]; 42 mark[x]=1; 43 int i,st=0; 44 f[x]=INF; 45 for(i=1;i<=sz;i++) 46 { 47 if(x & (1<<(i-1))) 48 { 49 if(!st) st=i; 50 else 51 { 52 if(d[st][i]!=-1) f[x]=min(f[x],dp(x^(1<<(st-1))^(1<<(i-1)))+d[st][i]); 53 } 54 } 55 } 56 return f[x]; 57 } 58 int main() 59 { 60 freopen("password.in","r",stdin); 61 freopen("password.out","w",stdout); 62 int i,x; 63 scanf("%d%d%d",&n,&k,&m); 64 for(i=1;i<=k;i++) 65 { 66 scanf("%d",&x); 67 P[x]^=1;P[x+1]^=1; 68 } 69 for(i=1;i<=n+1;i++) if(P[i]) bh[++sz]=i; 70 for(i=1;i<=m;i++) scanf("%d",&size[i]); 71 for(i=1;i<=sz;i++) bfs(i); 72 dp((1<<sz)-1); 73 if(f[(1<<sz)-1]==INF) printf("-1 "); 74 else printf("%d ",f[(1<<sz)-1]); 75 return 0; 76 }