NOIP模拟 7.01
水灾(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.忘记了特判xx > n 或者 yy > m导致RE。。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 inline void read(int &x) 10 { 11 x = 0;char ch = getchar();char c = ch; 12 while(ch < '0' || ch > '9')c = ch, ch = getchar(); 13 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); 14 if(c == '-')x = -x; 15 } 16 inline int max(int a, int b){return a > b ? a : b;} 17 inline int min(int a, int b){return a > b ? b : a;} 18 inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;} 19 20 const int INF = 0x3f3f3f3f; 21 const int MAXN = 1100 + 10; 22 const int MAXM = 1400 + 10; 23 const int dirx[4] = {0,0,1,-1}; 24 const int diry[4] = {1,-1,0,0}; 25 26 char g[MAXN][MAXM];int n,m; 27 bool b[MAXN][MAXM];//人不能在拓展的地方 28 bool bb[MAXN][MAXM];//洪水不能再拓展的地方 29 int ex,ey; 30 struct Node 31 { 32 int x,y,t;//t代表第几轮 33 }q[3500000]; 34 int cnt; 35 36 std::queue<int> q1,q2;//1为人的队列,2为洪水队列 37 38 inline int bfs() 39 { 40 int ans = 0; 41 Node tmp; 42 while(!q1.empty()) 43 { 44 int k; 45 //先做队列2 46 if(q2.empty())goto L1; 47 tmp = q[q2.front()]; 48 k = tmp.t; 49 while(!q2.empty()) 50 { 51 tmp = q[q2.front()]; 52 if(k != tmp.t)break; 53 q2.pop(); 54 for(int i = 0;i < 4;++ i) 55 { 56 int xx = tmp.x + dirx[i],yy = tmp.y + diry[i]; 57 if(xx <= 0 || yy <= 0 || xx > n || yy > m)continue; 58 if(!bb[xx][yy]) 59 { 60 q[++cnt] = Node{xx, yy, tmp.t + 1}; 61 bb[xx][yy] = b[xx][yy] = true; 62 q2.push(cnt); 63 } 64 } 65 } 66 //再做队列1 67 L1: tmp = q[q1.front()]; 68 k = tmp.t; 69 while(!q1.empty()) 70 { 71 tmp = q[q1.front()]; 72 if(k != tmp.t)break; 73 q1.pop(); 74 for(int i = 0;i < 4;++ i) 75 { 76 int xx = tmp.x + dirx[i],yy = tmp.y + diry[i]; 77 if(xx <= 0 || yy <= 0 || xx > n || yy > m)continue; 78 if(xx == ex && yy == ey)return k + 1; 79 if(!b[xx][yy]) 80 { 81 q[++cnt] = Node{xx, yy, tmp.t + 1}; 82 b[xx][yy] = true; 83 q1.push(cnt); 84 } 85 } 86 } 87 } 88 return -1; 89 } 90 91 int main() 92 { 93 read(n);read(m); 94 for(register int i = 1;i <= n;++ i) 95 { 96 scanf("%s", g[i] + 1); 97 for(register int j = 1;j <= m;++ j) 98 { 99 if(g[i][j] == 'D') 100 ex = i, ey = j, bb[i][j] = true; 101 else if(g[i][j] == 'X') 102 bb[i][j] = b[i][j] = true; 103 else if(g[i][j] == '*') 104 { 105 b[i][j] = bb[i][j] = true; 106 q[++cnt] = Node{i,j,0}; 107 q2.push(cnt); 108 } 109 else if(g[i][j] == 'S') 110 { 111 b[i][j] = true; 112 q[++cnt] = Node{i,j,0}; 113 q1.push(cnt); 114 } 115 } 116 } 117 int ans = bfs(); 118 if(ans == -1)printf("ORZ hzwer!!!"); 119 else printf("%d", ans); 120 return 0; 121 }
某种数列问题 (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=)。
f[i][j]表示前i个数选j段且第i - 1个数必须选所能获得的最大收益
f[i][0] = max(f[i - 1][0] + num[i], num[i])
f[i][1] = max(f[i - 1][1] + num[i], f[j][0] + num[i] j<i)
f[i][2] = max(f[i - 1][2] + num[i], f[j][1] + num[i] j<i)
用最大值优化一下即可
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 inline void read(long long &x){x = 0;char ch = getchar();char c = ch;while(ch < '0' || ch > '9')c = ch, ch = getchar();while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();if(c == '-')x = -x;} 10 inline long long max(long long a, long long b){return a > b ? a : b;} 11 inline long long min(long long a, long long b){return a > b ? b : a;} 12 inline void swap(long long &a, long long &b){int tmp = a;a = b;b = tmp;} 13 14 const long long INF = 0x3f3f3f3f3f3f3f3f; 15 const long long MAXN = 1500000 + 10; 16 17 long long num[MAXN]; 18 long long sum; 19 long long n; 20 long long ma; 21 22 long long f[MAXN][3]; 23 24 long long ma1, ma2; 25 26 long long ans; 27 28 int main() 29 { 30 read(n); 31 ma1 = ma2 = ans = -INF; 32 for(register int i = 1;i <= n;++ i) 33 read(num[i]); 34 f[1][0] = num[1]; 35 f[2][0] = max(num[1] + num[2], num[2]); 36 f[2][1] = num[1] + num[2]; 37 ma1 = max(f[1][0], f[2][0]); 38 ma2 = f[2][1]; 39 f[3][0] = max(f[2][0] + num[3], num[3]); 40 f[3][1] = max(f[2][1] + num[3], ma1 + num[3]); 41 f[3][2] = num[1] + num[2] + num[3]; 42 ma2 = max(ma2, f[3][1]); 43 ma1 = max(ma1, f[3][0]); 44 for(register int i = 4;i <= n;++ i) 45 { 46 f[i][0] = max(f[i - 1][0] + num[i], num[i]); 47 f[i][1] = max(f[i - 1][1] + num[i], ma1 + num[i]); 48 f[i][2] = max(f[i - 1][2] + num[i], ma2 + num[i]); 49 ma1 = max(ma1, f[i][0]); 50 ma2 = max(ma2, f[i][1]); 51 } 52 ans = f[3][2]; 53 for(register int i = 4;i <= n;++ i) 54 { 55 ans = max(ans, f[i][2]); 56 } 57 printf("%lld", ans); 58 return 0; 59 }
密码锁 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。
先挂在这里,以后再说。。。