CodeForces Round #292 Div.2

昨天注册了没有打,晚上给长辈们敬完酒,回来就洗洗睡了,=_=||

A. Drazil and Date

题意:

是否有可能恰好用s步,从原点走到(a, b)。

分析:

首先要走到终点至少要|a|+|b|步,如果还剩多余的步数的话,那就向右走一格再走回来。

也就是s要比|a|+|b|多偶数步(包括0)才可以。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int a, b, s;
 9     scanf("%d%d%d", &a, &b, &s);
10     a = abs(a); b = abs(b);
11     bool ans;
12     if(a+b<=s && ((a+b)-s)%2==0) ans = true;
13     else ans = false;
14     printf("%s\n", ans ? "Yes" : "No");
15 
16     return 0;
17 }
代码君

 

B. Drazil and His Happy Friends

题意:

有n个男孩和m个女孩,有的开心有的不开心。可以把第(i mod n)个男孩和第(i mod m)个女孩拉出来一起吃晚饭,只要两个人中有一个是开心的,吃完饭两个人都是开心的。

问是否可以把所有的男孩女孩变开心。

分析:

也就是说开心是可以“传染”的,那我们就枚举所有可能约会的情况,尽量让更多的人变开心。

每次枚举的上限是多少呢?应该是LCM(n, m)

枚举直到开心的人数不再增多为止

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 const int maxn = 100 + 10;
 6 
 7 int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); }
 8 
 9 int lcm(int a, int b) { return a / gcd(a, b) * b; }
10 
11 bool boys[maxn], girls[maxn];
12 
13 int main()
14 {
15     //freopen("in.txt", "r", stdin);
16 
17     int n, m, b, g, x, y;
18     scanf("%d%d", &n, &m);
19     scanf("%d", &b);
20     for(int i = 0; i < b; ++i) { scanf("%d", &x); boys[x] = true; }
21     scanf("%d", &g);
22     for(int i = 0; i < g; ++i) { scanf("%d", &x); girls[x] = true; }
23 
24     int G = lcm(n, m);
25 
26     for(;;)
27     {
28         bool flag = false;
29         for(int i = 0; i < G; ++i)
30         {
31             x = i % n; y = i % m;
32             if(boys[x] && !girls[y]) { girls[y] = true; g++; flag = true; }
33             if(!boys[x] && girls[y]) { boys[x] = true; b++; flag = true; }
34         }
35         if(!flag) break;
36     }
37 
38     if(b == n && g == m) puts("Yes"); else puts("No");
39 
40     return 0;
41 }
代码君

 

C. Drazil and Factorial

题意:

令F(x)为x各个数字的阶乘的乘积,比如F(1234) = 1!2!3!4! = 288

现在给出一个x,求y的最大值使得F(x) = F(y),并且y中不含0和1.

分析:

在样例中F(1234) = F(33222),我们仔细观察一下,发现其实是4!被分解成了2!2!3!

再比如 6! = 3!5!

所以我们把2~9这些数字尽可能分解成多的数字,然后从大到小排序,就是答案。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 string a[10] = {"", "", "2", "3", "223", "5", "35", "7", "2227", "7233"};
 6 
 7 int main()
 8 {
 9     int n;
10     string s, ans;
11     cin >> n >> s;
12     for(int i = 0; i < n; ++i) ans += a[s[i]-'0'];
13     sort(ans.begin(), ans.end());
14     reverse(ans.begin(), ans.end());
15     cout << ans << endl;
16 
17     return 0;
18 }
代码君

 

D. Drazil and Tiles (贪心 BFS)

题目太长了,直接说思路吧。

把每个空位置看做一个点,如果与它相邻还有个空位置,也就是能放一个1×2的砖块,就叫做有一个度。

因为要找放砖块的唯一解,所以我们从度数为1的点开始放。如果没有的话,说明无解或多解,直接输出“Not unique”

然后BFS,度数为1的点放砖块只有一个方向,所以我们边BFS边放砖块,并及时更新度数,如果出现了新的度数为1的点就加到队列里面去。

BFS完后再判断一下是否所有的空位置都放上砖块了。

 1 #include <bits/stdc++.h>
 2 #define PII pair<int,int>
 3 #define MP make_pair
 4 #define F first
 5 #define S second
 6 using namespace std;
 7 
 8 const int maxn = 2000 + 10;
 9 
10 char s[maxn][maxn];
11 int deg[maxn][maxn];
12 
13 int dx[] = {1, 0, -1, 0};
14 int dy[] = {0, 1, 0, -1};
15 char fillchar[2][5] = { "^<v>", "v>^<" };
16 
17 inline int caldeg(int i, int j)//计算该点的度数
18 { return (int)(s[i-1][j] == '.') + (int)(s[i+1][j] == '.') + (int)(s[i][j-1] == '.') + (int)(s[i][j+1] == '.'); }
19 
20 int main()
21 {
22     //freopen("in.txt", "r", stdin);
23 
24     int n, m;
25     scanf("%d%d", &n, &m);
26     for(int i = 1; i <= n; ++i) scanf("%s", s[i]+1);
27 
28     queue<PII> Q;
29     int cnt = 0;
30     for(int i = 1; i <= n; ++i)
31         for(int j = 1; j <= m; ++j) if(s[i][j] == '.')
32         {
33             deg[i][j] = caldeg(i, j);
34             cnt++;
35             if(deg[i][j] == 1)
36                 Q.push(MP(i, j));
37         }
38 
39     if(cnt & 1) { puts("Not unique"); return 0; }
40 
41     while(!Q.empty())
42     {
43         PII cur = Q.front(); Q.pop();
44         int x = cur.F; int y = cur.S;
45         if(s[x][y] == '.')
46         {
47             int i, nx, ny;
48             for(i = 0; i < 4; ++i)
49             {
50                 nx = x + dx[i];
51                 ny = y + dy[i];
52                 if(s[nx][ny] == '.') break;
53             }
54             if(i == 4) { puts("Not unique"); return 0; }
55             s[x][y] = fillchar[0][i];//放砖块
56             s[nx][ny] = fillchar[1][i];
57             deg[x][y] = deg[nx][ny] = 0;
58             cnt -= 2;
59             for(i = 0; i < 4; ++i)
60             {
61                 int nnx = nx + dx[i];
62                 int nny = ny + dy[i];
63                 if(s[nnx][nny] == '.')
64                 {
65                     deg[nnx][nny]--;//更新周围点的度数
66                     if(deg[nnx][nny] == 1) Q.push(MP(nnx, nny));
67                 }
68             }
69         }
70     }
71 
72     if(cnt != 0) puts("Not unique");//还存在空位置
73     else
74         for(int i = 1; i <= n; ++i) printf("%s\n", s[i]+1);
75 
76     return 0;
77 }
代码君

 

posted @ 2015-02-18 14:46  AOQNRMGYXLMV  阅读(181)  评论(0编辑  收藏  举报