CF #301 div2
来源:互联网 发布:做编程用什么电脑配置 编辑:程序博客网 时间:2024/05/01 16:06
A:
题意:
给两个串t,p,像密码锁那样每次滑动一个,问最短滑动多少次。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);char p[maxn];char t[maxn];int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL int n; scanf("%d", &n); scanf("%s%s", p, t); int ans = 0; for (int i = 0; i < n; i++) { int pp = p[i] - '0'; int tt = t[i] - '0'; ans += min(abs(pp - tt), 10 - abs(pp - tt)); } cout << ans << endl; return 0;}
B:
题意:
天才小明有n门考试,已经考了k门,每一门的考试分数范围是1~p,他太厉害了可以控制自己考试分数考在范围内的任意分数上。
小明为了不让自己太装逼,所以他想让自己的分数的和小于等于x,但是为了让他妈继续给他打游戏,他成绩的中位数又不能低于y。
现在给你已经考了k门的课程的成绩,让你计算余下满足要求的n - k门考试他应该考多少分。
解析:
这题数据太神了。
首先先确定,为了让分数小于等于x,中位数不低于y,考的任意分数就可以确定了,最低用1,最高用y,这样处理就可以让两个条件满足并且简化。
然后为了使中位数落在y之上,最后分数集合中大于等于y的数应该大于小于等于y的数的。
所以用余下的分数总和除以y来计算最多可以放入多少个y,然后协调左右,计算出结果。
注意的是,给的数据中,有可能可以放入的y的个数远远大于余下课程数量,所以要加个取小的数的判断。,。
并且,在确定了之后,还要调整大于y的个数和小于y的个数。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL int n, k, p, x, y; scanf("%d%d%d%d%d", &n, &k, &p, &x, &y); int sumMark = 0; int greaterThan = 0; int lessThan = 0; for (int i = 0; i < k; i++) { int t; scanf("%d", &t); sumMark += t; if (y <= t) { greaterThan++; } else { lessThan++; } } int remainNum = n - k; int remainSum = x - sumMark;// cout << remainNum << " " << remainSum << endl;// cout << greaterThan << " " << lessThan << endl; int cntGT = remainSum / y; int cntLT = remainNum - cntGT;// cout << cntGT << " " << cntLT << endl; cntGT = min(cntGT, remainNum); cntLT = remainNum - cntGT; while (cntGT * y + 1 * cntLT > remainSum && cntGT != -1) { cntGT--; cntLT++; } if (cntGT == -1) { printf("-1\n"); } else {// cout << cntGT << " " << cntLT << endl; if (cntGT + greaterThan < cntLT + lessThan) { printf("-1\n"); } else {// cout << cntGT << " " << cntLT << endl; for (int i = 0; i < cntGT; i++) { printf("%d ", y); } for (int i = 0; i < cntLT; i++) { printf("1 "); } } } return 0;}
C:
题意:
给一个n * m的冰面。
“ . ” 代表这个冰面还没有被踩过;“ X ”表示这个冰面已经被踩过了,再次踩这个冰面的时候就会掉下去。
现在小明从 sx,sy出发,问他能否从 ex, ey,这个点掉到冰面下去。
解析:
开始弱智了,想先找到ex,ey然后去找某条路径能回到ex,ey。
然后LGG提醒,找到ex,ey之后,若ex,ey是“X”,那就直接YES了;
如果不是,只要判断终点周围存不存在“ . ", 如果存在,肯定能回到ex,ey并且掉下去。
所以先用bfs() , O(n)找到终点,并且标记上每一点的step。
找到终点后,判断周围有”."并且未被step标记或者周围有”.",标记的step大于终点的step,或者周围有”."并且有两个相等的step,即YES,否则NO。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 500 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int dir[][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};int n, m;char g[maxn][maxn];int sx, sy, ex, ey;int step[maxn][maxn];struct Node{ int x, y; Node(int _x, int _y) { x = _x; y = _y; }};bool isOk(int x, int y){ int ans[4]; int cnt = 0; for (int i = 0; i < 4; i++) { int nx = x + dir[i][0]; int ny = y + dir[i][1]; if (0 <= nx && nx < n && 0 <= ny && ny < m) { if ((step[nx][ny] == -1 && g[nx][ny] == '.') || step[x][y] < step[nx][ny]) return true; else if (step[nx][ny] != -1) ans[cnt++] = step[nx][ny]; } }// cout << cnt << endl; sort(ans, ans + cnt);// for (int i = 0; i < cnt; i++)// cout <<ans[i]<< endl; for (int i = 1; i < cnt; i++) if (ans[i - 1] == ans[i]) return true; return false;}bool bfsFindWay(){ memset(step, -1, sizeof(step)); queue<Node> q; step[sx][sy] = 0; q.push(Node(sx, sy)); while (!q.empty()) { Node now = q.front(); q.pop(); int x = now.x; int y = now.y; if (x == ex && y == ey) { return isOk(ex, ey); } for (int i = 0; i < 4; i++) { int nx = x + dir[i][0]; int ny = y + dir[i][1]; if (0 <= nx && nx < n && 0 <= ny && ny < m) { if (nx == ex && ny == ey && g[nx][ny] == 'X') return true; if (g[nx][ny] != 'X') { if (step[nx][ny] == -1) { step[nx][ny] = step[x][y] + 1; q.push(Node(nx, ny)); } } } } } return false;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%s", g[i]); } scanf("%d%d%d%d", &sx, &sy, &ex, &ey); sx--, sy--, ex--, ey--; if (bfsFindWay()) { printf("YES\n"); } else { printf("NO\n"); }// for (int i = 0; i < n; i++)// {// for (int j = 0; j < m; j++)// {// printf("%5d ", step[i][j]);// }// printf("\n");// } return 0;}
D:
题意:
有三种生物生活在一个海岛上,锤子,剪刀,布,他们之间锤子可以吃剪刀,剪刀吃布,布吃锤子,每种生物相遇的概率是一样的。
现在给出三种生物的初始数量,计算经过足够长的时间以后,只剩下锤子的概率R,只剩下剪刀的概率S,只剩下布的概率P。。
解析:
设当前有锤子r只,剪刀s只,布p只,则锤子吃了剪刀的概率是: r * s / (r * s + r * p + s * p)。
所以 dp[ i ] [ j ] [ k ] 表示海岛上只剩下i只锤子,j只剪刀,k只布的时候的概率。
若布吃了锤子:
if (j != 0 || k != 0) dp[i][j][k] += ((i + 1.0) * k / ((i + 1) * j + (i + 1) * k + j * k)) * dp[i + 1][j][k];若锤子吃了剪刀:
if (i != 0 || k != 0) dp[i][j][k] += ((j + 1.0) * i / (i * (j + 1) + i * k + (j + 1) * k)) * dp[i][j + 1][k];若剪刀吃了布:
if (i != 0 || j != 0) dp[i][j][k] += ((k + 1.0) * j / (i * j + i * (k + 1) + j * (k + 1))) * dp[i][j][k + 1];
初始状态下:
dp[ r ] [ s ] [ p ] = 1
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 100 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);double dp[maxn][maxn][maxn];int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL int r, s, p; scanf("%d%d%d", &r, &s, &p); memset(dp, 0, sizeof(dp)); dp[r][s][p] = 1.0; for (int i = r; i >= 0; i--) { for (int j = s; j >= 0; j--) { for (int k = p; k >= 0; k--) { ///all die, all live if ((i == 0 && j == 0 && k == 0) || (i == r && j == s && k == p)) continue; ///k ate a i if (j != 0 || k != 0) dp[i][j][k] += ((i + 1.0) * k / ((i + 1) * j + (i + 1) * k + j * k)) * dp[i + 1][j][k]; ///i ate a j if (i != 0 || k != 0) dp[i][j][k] += ((j + 1.0) * i / (i * (j + 1) + i * k + (j + 1) * k)) * dp[i][j + 1][k]; ///j ate a k if (i != 0 || j != 0) dp[i][j][k] += ((k + 1.0) * j / (i * j + i * (k + 1) + j * (k + 1))) * dp[i][j][k + 1]; } } } double R = 0, S = 0, P = 0; for (int i = 1; i <= r; i++) R += dp[i][0][0]; for (int i = 1; i <= s; i++) S += dp[0][i][0]; for (int i = 1; i <= p; i++) P += dp[0][0][i]; printf("%.12lf %.12lf %.12lf\n", R, S, P); return 0;}
- cf 301 div2
- CF #301 div2
- cf 131 DIV2 B
- CF #148 DIV2 E
- CF #137 DIV2
- CF 149 div2感想
- CF-div2--149
- CF 154 Div2
- cf-#170-div2-后记
- cf#168div2
- cf#167div2
- cf#166div2
- CF 183(div2)
- CF 173(div2) B
- cf#div2--184
- CF 174(div2) D
- CF 165(div2)
- CF 168(div2)
- codeforces 548 C Mike and Frog
- C#Winform 中,两个form之间参数传递
- HTTP 304 Not Modified
- Java开发环境之Spring+SpringMVC+Mybatis整合demo
- iOS 查看lib库(.a)支持的处理器架构、合并真机库和模拟器库的命令
- CF #301 div2
- Ubuntu下deb包的安装方法
- WPF笔记
- Git使用初步
- UNIX Domain Socket IPC (sockaddr_un )
- 批量将Java源代码文件的编码从GBK转为UTF-8
- @repository注解
- (转)Hadoop c++开发
- C语言实现swap的四种方式