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 }