CodeForces 220(div 2)

悲剧的div2。。。。。

A

题意:在n * m的矩形平面直角坐标系中,从(x, y)可以到四个点(x - a, y - b),(x + a, y - b),(x - a, y + b),(x + a, y + b)。给定坐标(x, y)和a, b, n, m,求该点走到矩形顶点( (1, m)(n, 1)(n, m)(1, 1)中任意一个)最少需要多少步。如果走不到,返回-1。

解法:枚举一下走到哪个顶点就行了。关键是有两个trick,一个是不能走出矩形边界,另一个是比如(3, 2),a = b = 1走不到(1, 1)。注意特判就好了。

tag:水题, trick

 1 /*
 2  * Author:  Plumrain
 3  * Created Time:  2013-12-18 23:33
 4  * File Name: A.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <string>
10 #include <cmath>
11 #include <algorithm>
12 #include <vector>
13 #include <cstdlib>
14 #include <sstream>
15 #include <fstream>
16 #include <list>
17 #include <deque>
18 #include <queue>
19 #include <stack>
20 #include <map>
21 #include <set>
22 #include <bitset>
23 #include <cctype>
24 #include <ctime>
25 #include <utility>
26 
27 using namespace std;
28 
29 #define CLR(x) memset(x, 0, sizeof(x))
30 #define PB push_back
31 #define SZ(v) ((int)(v).size())
32 #define ALL(t) t.begin(),t.end()
33 #define INF 999999999999
34 #define zero(x) (((x)>0?(x):-(x))<eps)
35 #define out(x) cout<<#x<<":"<<(x)<<endl
36 #define tst(a) cout<<#a<<endl
37 #define CINBEQUICKER std::ios::sync_with_stdio(false)
38 
39 const double eps = 1e-8;
40 const double PI = atan(1.0)*4;
41 const int maxint = 2147483647;
42 
43 typedef vector<int> VI;
44 typedef vector<string> VS;
45 typedef vector<double> VD;
46 typedef pair<int, int> pii;
47 typedef long long int64;
48 
49 inline int Mymod (int a, int b) {int x=a%b; if(x<0) x+=b; return x;}
50 
51 int n, m, x, y, a, b;
52 int gao(int x, int y, int ta, int tb)
53 {
54     int da = abs(x - ta), db = abs(y - tb);
55     if (da % a) return maxint;
56     if (db % b) return maxint;
57     
58     int t1 = da / a, t2 = db / b;
59     if (abs(t1-t2) & 1) return maxint;
60     if (t1 == t2) return t1;
61     if (t1 < t2){
62         if (n < 2*a) return maxint;
63         return t2;
64     }
65     else{
66         if (m < 2*b) return maxint;
67         return t1;
68     }
69 }
70 
71 int main()
72 {
73 //    freopen("a.in","r",stdin);
74 //    freopen("a.out","w",stdout);
75 //    std::ios::sync_with_stdio(false);
76     while (cin >> n >> m >> x >> y >> a >> b){
77         int ans = min(gao(x, y, 1, 1), gao(x, y, 1, m));
78         ans = min(ans, gao(x, y, n, m));
79         ans = min(ans, gao(x, y, n, 1));
80         if (ans == maxint) cout << "Poor Inna and pony!" << endl;
81         else cout << ans << endl;
82     }
83     return 0;
84 }
View Code

 

 

B

题意:给一个有'1' - '9'组成的字符串s,可以进行一种操作,就是如果s[i]-‘0’ + s[i+1]-‘0' == 9,可以在s中用'9'替换s[i]和s[i+1]。问在最终得到的字符串s含有9数量最多的前提下,最终操作完成后可能得到多少种字符串。s.size() <= 10^5。

解法:考虑连续几个和都为9的情况,比如34343,如果子串长度为偶数,则只有一种操作方法。否则,有(len+1) / 2种处理方法。每个子串的处理方法数相乘即为答案。

tag:水题

 1 /*
 2  * Author:  Plumrain
 3  * Created Time:  2013-12-18 23:44
 4  * File Name: B.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <string>
10 #include <cmath>
11 #include <algorithm>
12 #include <vector>
13 #include <cstdlib>
14 #include <sstream>
15 #include <fstream>
16 #include <list>
17 #include <deque>
18 #include <queue>
19 #include <stack>
20 #include <map>
21 #include <set>
22 #include <bitset>
23 #include <cctype>
24 #include <ctime>
25 #include <utility>
26 
27 using namespace std;
28 
29 #define CLR(x) memset(x, 0, sizeof(x))
30 #define PB push_back
31 #define SZ(v) ((int)(v).size())
32 #define ALL(t) t.begin(),t.end()
33 #define INF 999999999999
34 #define zero(x) (((x)>0?(x):-(x))<eps)
35 #define out(x) cout<<#x<<":"<<(x)<<endl
36 #define tst(a) cout<<#a<<endl
37 #define CINBEQUICKER std::ios::sync_with_stdio(false)
38 
39 const double eps = 1e-8;
40 const double PI = atan(1.0)*4;
41 const int maxint = 2147483647;
42 
43 typedef vector<int> VI;
44 typedef vector<string> VS;
45 typedef vector<double> VD;
46 typedef pair<int, int> pii;
47 typedef long long int64;
48 
49 inline int Mymod (int a, int b) {int x=a%b; if(x<0) x+=b; return x;}
50 
51 int64 two[100];
52 int a[100005];
53 
54 int main()
55 {
56 //    freopen("a.in","r",stdin);
57 //    freopen("a.out","w",stdout);
58 //    std::ios::sync_with_stdio(false);
59     two[0] = 1;
60     for (int i = 1; i < 63; ++ i)
61         two[i] = two[i-1] * 2;
62 
63     string s;
64     while (cin >> s){
65         int n = s.size();
66         for (int i = 0; i < n; ++ i)
67             a[i] = s[i] - '0';
68 
69         int num = 1;
70         int64 ans = 1;
71         for (int i = 1; i < n; ++ i){
72             if (a[i] + a[i-1] == 9)
73                 num ++;
74             else{
75                 if (num > 1 && num & 1) ans *= (num/2+1);
76                 num = 1;
77             }
78         }
79         if (num > 1 && num & 1) ans *= (num/2+1);
80         cout << ans << endl;
81     }
82     
83     return 0;
84 }
View Code

 

C

题意:一个由四个字符——D,I,M,A——组成的n*m的矩阵中,能从写有D的格子走到I,I走到M,M走到A,A走回D。可以从任意写有D的格子开始,问最多能走多少组DIMA。

解法:简单DFS加记忆化。比赛的时候sb了。。。

tag:DFS, memorization

方法比较裸,比完以后我就没补这道题了。

 

D

题意:给一个数组an[],然后读入一串数并维护以个队列。若读到0或1,则将它放在队尾;若读到-1,则找到最大的i使得an[i] <= len(当前队列的长度),然后同时在队列中删除位置为an[0], an[1]....an[i]的元素。问最终得到的队列是什么。an.size() <= 10^6,读入的一串数最多10^6,1 <= an[i] <= 10^6。

解法:比赛的时候我写了个用并查集的方法,后来发现是错的。好像可以用后缀数组来做,O(n*logn*logn)的方法。不过我不会。。。。还有神牛写了O(n)的方法。

   关键点在于:用扫一遍可以直到,每次将0/1放进去的时候,队列的长度是多少,也即是知道这个数放进去的位置在哪。又即是说,只要提前预处理出每个位置在放了数以后,需要多少个-1操作才能把这一位删掉,这个问题就能得到解决。至于具体操作细节,看代码。

tag:think, dp, good

 1 /*
 2  * Author:  Plumrain
 3  * Created Time:  2013-12-24 14:19
 4  * File Name: D.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <vector>
10 
11 using namespace std;
12 
13 #define clr0(x) memset(x, 0, sizeof(x))
14 #define pb push_back
15 #define sz(v) ((int)(v).size())
16 #define out(x) cout<<#x<<":"<<(x)<<endl
17 #define tst(a) cout<<a<<" "
18 const int inf = 2147483647 / 2;
19 const int N = 1000005;
20 typedef vector<int> vi;
21 
22 int n, m;
23 int opt[N];
24 int an[N], d[N], flag[N];
25 
26 int bin_search(int x)
27 {
28     int l = 0, r = m-1;
29     while (l <= r){
30         int mid = (l + r) >> 1;
31         if (an[mid] <= x) l = mid + 1;
32         else r = mid - 1;
33     }
34     return r;
35 }
36 
37 int main()
38 {
39     while (scanf ("%d%d", &n, &m) != EOF){
40         clr0 (d); clr0 (flag);
41         for (int i = 0; i < m; ++ i)
42             scanf ("%d", &an[i]);
43         int idx = 0, p = 1, num = 0;
44         while (idx < m){
45             if (!idx && p != an[0]) d[p] = inf;
46             else{
47                 if (p == an[idx]){
48                     d[p] = 1;
49                     ++ num; ++ idx;
50                 }
51                 else d[p] = d[p-num] + 1;
52             }
53             ++ p;
54         }
55         for (int i = p; i <= 1000000; ++ i)
56             d[i] = d[i-num] + 1;
57         
58         int len = 0;
59         for (int i = 0; i < n; ++ i){
60             scanf ("%d", &opt[i]);
61             if (opt[i] == -1) len -= 1 + bin_search(len);
62             else flag[i] = d[++len];
63         }
64         vi v;
65         int cnt = 0;
66         for (int i = n-1; i >= 0; -- i){
67             if (opt[i] == -1) ++ cnt;
68             else if (flag[i] > cnt) v.pb (opt[i]);
69         }
70 
71         if (!sz(v)) printf ("Poor stack!");
72         else for (int i = sz(v)-1; i >= 0; -- i)
73             printf ("%d", v[i]);
74         printf ("\n");
75     }
76     return 0;
77 }
View Code

 

E

没做。

 

 

posted @ 2013-12-24 15:19  Plumrain  阅读(216)  评论(0编辑  收藏  举报