Codeforces Round-#373 (Div. 2 && Div. 1) [Codeforces719 && 718]
来源:互联网 发布:哪个软件有鱼眼效果 编辑:程序博客网 时间:2024/05/01 19:55
题目链接
Div. 1
Div. 2
官方题解
719 - A - Vitya in the Countryside
题目大意
一个月有
思路 - 模拟
按照题意判断即可,注意坑点有最后一天是
代码
#include <cstdio>using namespace std;int n, pre, cur;int main() { while(1 == scanf("%d", &n)) { scanf("%d", &cur); for(int i = 1; i < n; ++i) { pre = cur; scanf("%d", &cur); } if(cur == 0) { printf("UP\n"); } else if(cur == 15) { printf("DOWN\n"); } else if(n == 1) { printf("-1\n"); } else { printf("%s\n", pre < cur ? "UP" : "DOWN"); } } return 0;}
719 - B - Anatoly and Cockroaches
题目大意
有一个
思路 - 贪心
按照题目要求,再枚举奇数位放
代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int n;int getMin(int cnt_b[3], int cnt_r[3]) { int num = n / 2 + (n & 1), tmp;//num为r字符的应有值 //令第一个字符为r字符 if(cnt_r[0] + cnt_r[1] <= num) {//若r的字符个数小于等于应有值,则需要将b字符转换成r字符 tmp = num - cnt_r[0] - cnt_r[1];//需要将tmp个b字符转换成r字符 //可以确定在0,2,4...的b字符一定大于等于tmp,否则不满足字符数等于应有值 cnt_b[0] -= tmp;//将所有需要转换的字符都在正确位置转换 tmp += cnt_b[0];//剩余的不在正确位置的b字符需要交换操作 } else {//需要将r字符转换成b字符 tmp = cnt_r[0] + cnt_r[1] - num;//需要将tmp个r字符转换成b字符 if(cnt_r[1] >= tmp) { cnt_r[1] -= tmp; } else { cnt_r[1] -= tmp - cnt_r[0]; cnt_r[1] = 0; } tmp += cnt_b[0];//剩余的不在正确位置的b字符需要交换操作 } return tmp;}int cnt_b[3][3], cnt_r[3][3], ans, tmp, num;char s[100003];int main() { while(1 == scanf("%d", &n)) { scanf("%s", s); cnt_b[0][0] = cnt_b[0][1] = cnt_r[0][0] = cnt_r[0][1] = 0; cnt_b[1][0] = cnt_b[1][1] = cnt_r[1][0] = cnt_r[1][1] = 0; for(int i = 0; i < n; ++i) {//统计每个字符在奇数位和偶数位出现的次数 if(s[i] == 'b') { ++cnt_b[0][i & 1]; ++cnt_b[1][i & 1]; } else { ++cnt_r[0][i & 1]; ++cnt_r[1][i & 1]; } } printf("%d\n", min(getMin(cnt_b[0], cnt_r[0]), getMin(cnt_r[1], cnt_b[1]))); } return 0;}
618 - A - Efim and Strange Grade
题目大意
给定一个小数,可以对小数部分最多进行
思路 - 模拟
从小数点后第一个大于等于
题解用的是
代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int n, t, pos, ed, carry;char s[200003];int main() { while(2 == scanf("%d%d", &n, &t)) { scanf("%s", s + 1); s[0] = '0'; for(pos = 1; pos <= n; ++pos) { if(s[pos] == '.') { break; } } int i; for(i = 1; i <= n; ++i) { if(i > pos && '5' <= s[i] && s[i] <= '9') { if(i - 1 == pos) { ++s[i - 2]; s[i - 1] = '\0'; i -= 2; } else { ++s[i - 1]; if(i > pos) { s[i] = '\0'; } --i; } carry = (s[i] == '0' + 10) ? 1 : 0; --t; break; } } if(i <= n) { while(i > pos && t > 0 && '5' <= s[i]) { if(i - 1 == pos) { ++s[i - 2]; s[i - 1] = '\0'; i -= 2; } else { ++s[i - 1]; if(i > pos) { s[i] = '\0'; } --i; } carry = (s[i] == '0' + 10) ? 1 : 0; --t; } } while(carry == 1) { s[i] = '0'; if(i - 1 == pos) { ++s[i - 2]; s[i - 1] = '\0'; i -= 2; } else { ++s[i - 1]; if(i > pos) { s[i] = '\0'; } --i; } carry = (s[i] == '0' + 10) ? 1 : 0; } printf("%s\n", s[0] == '0' ? s + 1 : s); } return 0;}
718 - C - Sasha and Array
题目大意
给定一个数列
①
①
思路 - 线段树 && 矩阵快速幂
肯定能想到用矩阵快速幂求斐波那契数列,但是没有想到利用矩阵快速幂的方法,用线段树维护矩阵。
叶子结点维护
代码
#include <cstdio>#include <cstring>#include <algorithm>#define lson (i << 1)#define rson ((i << 1) | 1)using namespace std;const int MAXN = 100003;const int MAX_MAT = 2;const long long MOD = 1e9+7;struct Matrix { int m[MAX_MAT][MAX_MAT]; bool operator == (const Matrix& b) const { for(int i = 0; i < MAX_MAT; ++i) { for(int j = 0; j < MAX_MAT; ++j) { if(m[i][j] != b.m[i][j]) { return false; } } } return true; } Matrix operator + (const Matrix& b) const { Matrix c; for(int i = 0; i < MAX_MAT; ++i) { for(int j = 0; j < MAX_MAT; ++j) { c.m[i][j] = (m[i][j] + b.m[i][j]) % MOD; } } return c; } Matrix operator - (const Matrix& b) const { Matrix c; for(int i = 0; i < MAX_MAT; ++i) { for(int j = 0; j < MAX_MAT; ++j) { c.m[i][j] = (m[i][j] - b.m[i][j] + MOD) % MOD; } } return c; } Matrix operator * (const Matrix& b) const { Matrix c; for(int i = 0; i < MAX_MAT; ++i) { for(int j = 0; j < MAX_MAT; ++j) { long long res = 0; for(int k = 0; k < MAX_MAT; ++k) { res += ((long long) m[i][k]) * b.m[k][j]; } c.m[i][j] = res % MOD; } } return c; } Matrix operator ^ (long long n) const;};const Matrix FIB = {1, 1, 0, 0};const Matrix P = {0, 1, 1, 1,};const Matrix I = {1, 0, 0, 1,};//由于使用了结构体本身的常量,所以需要定义成外部成员函数Matrix Matrix :: operator ^ (long long n) const { Matrix m = *this, b = I; while(n > 0) { if((n & 1) == 1) { b = b * m; } n = n >> 1; m = m * m; } return b;}struct Node { int l, r; Matrix sum, lazy;//刚开始一直把lazy存成指数,导致花式TLE}tr[MAXN << 2];int n, m;int ope, L, R, X;inline void pushDown(int i) { if(!(tr[i].lazy == I) && tr[i].l != tr[i].r) {//叶子结点不下放,否则会越界 tr[lson].sum = tr[lson].sum * tr[i].lazy; tr[lson].lazy = tr[lson].lazy * tr[i].lazy; tr[rson].sum = tr[rson].sum * tr[i].lazy; tr[rson].lazy = tr[rson].lazy * tr[i].lazy; tr[i].lazy = I; }}inline void pushUp(int i) { tr[i].sum = tr[lson].sum + tr[rson].sum;}void build(int i, int l, int r) { tr[i].l = l; tr[i].r = r; tr[i].lazy = I; if(l == r) { scanf("%d", &X); tr[i].sum = FIB; tr[i].sum = tr[i].sum * (P ^ (X - 1)); return ; } int mid = (l + r) >> 1; build(lson, l, mid); build(rson, mid + 1, r); pushUp(i);}void modify(int i, const Matrix& temp) { if(L <= tr[i].l && tr[i].r <= R) { tr[i].sum = tr[i].sum * temp; tr[i].lazy = tr[i].lazy * temp; return ; } pushDown(i); int mid = tr[lson].r; if(mid >= L) { modify(lson, temp); } if(mid < R) { modify(rson, temp); } pushUp(i);}int query(int i) { if(L <= tr[i].l && tr[i].r <= R) { return tr[i].sum.m[0][0]; } pushDown(i); int mid = tr[lson].r; int res = 0; if(mid >= L) { res = query(lson); } if(mid < R) { res += query(rson); } pushUp(i); return res % MOD;}int main() { while(2 == scanf("%d%d", &n, &m)) { build(1, 1, n); while(m-- >0) { scanf("%d%d%d", &ope, &L, &R); if(ope == 1) { scanf("%d", &X); modify(1, P ^ X); } else { printf("%d\n", query(1)); } } } return 0;}
718 - D - Andrew and Chemistry
题目大意
给定一颗无根树,现可以添加一个结点,使得添加后形成不同构的树有多少?保证添加前后每个结点的度不能超过
思路 - 树形DP
题解的方法好巧妙,由于每个结点
可以想到
可以不枚举,再从上往下更新状态值就能得到所有点作为根时的状态值。大致是递归前,令当前结点
代码
#include <cstdio>#include <cstring>#include <map>#include <algorithm>#define lson (i << 1)#define rson ((i << 1) | 1)using namespace std;const int MAXN = 100003;const int INF = 0x3f3f3f3f;struct Vect { int a[4]; Vect() { memset(a, 0x3f, sizeof(a)); } bool operator < (const Vect& x) const { for(int i = 0; i < 4; ++i) { if(a[i] != x.a[i]) { return a[i] < x.a[i]; } } return false; }};struct Node { int v, nxt;}edge[MAXN << 1];int fir[MAXN], tot;void init() { memset(fir, -1, sizeof(fir)); tot = 0;}void addEdge(int u, int v) { edge[tot].v = v; edge[tot].nxt = fir[u]; fir[u] = tot++; edge[tot].v = u; edge[tot].nxt = fir[v]; fir[v] = tot++;}int n, ans, cnt;//a[i]表示只看子结点时的状态值,b[i]表示看所有结点时的状态值int a[MAXN], b[MAXN], deg[MAXN];//deg[i]表示i点的度bool vis[MAXN * 3];//【注意】由于dfsFromDown中cnt至多+n次,dfsFromUp中cnt至多+(n+n)次,所以要开三倍空间map<Vect, int> mp;void dfsFromDown(int u, int p) {//自底向上更新a Vect cur; int num = 0, v; for(int i = fir[u]; i != -1; i = edge[i].nxt) { v = edge[i].v; if(v != p) { dfsFromDown(v, u); cur.a[num++] = a[v]; } } sort(cur.a, cur.a + 4);//按子结点状态的升序排序 if(mp[cur] == 0) {//如果当前状态未出现过,则标记为一个新的状态 mp[cur] = ++cnt; } a[u] = mp[cur];}//status表示p结点以u结点为父亲结点时应有的状态值a[p]void dfsFromUp(int u, int p, int status) {//自顶向下更新b Vect cur; int num = 0, v; for(int i = fir[u]; i != -1; i = edge[i].nxt) { v = edge[i].v; if(v == p) { cur.a[num++] = status; } else { cur.a[num++] = a[v]; } } sort(cur.a, cur.a + 4);//按子结点状态的升序排序 if(mp[cur] == 0) {//如果当前状态未出现过,则标记为一个新的状态 mp[cur] = ++cnt; } b[u] = mp[cur]; for(int i = fir[u]; i != -1; i = edge[i].nxt) { v = edge[i].v; if(v != p) { for(int i = 0; i < 4; ++i) { if(cur.a[i] == a[v]) { cur.a[i] = INF; break; } } sort(cur.a, cur.a + 4);//按子结点状态的升序排序 if(mp[cur] == 0) {//如果当前状态未出现过,则标记为一个新的状态 mp[cur] = ++cnt; } dfsFromUp(v, u, mp[cur]); cur.a[3] = a[v]; } }}int u, v;int main() { while(1 == scanf("%d", &n)) { init(); mp.clear(); ans = cnt = 0; memset(deg, 0, sizeof(deg)); memset(vis, false, sizeof(vis)); for(int i = 1; i < n; ++i) { scanf("%d%d", &u, &v); addEdge(u, v); ++deg[u]; ++deg[v]; } dfsFromDown(1, 0); dfsFromUp(1, 0, 0); for(int i = 1; i <= n; ++i) { if(deg[i] < 4 && !vis[b[i]]) {//当前结点的度小于4且状态未出现过,则可以添一个结点形成新的不同的树 vis[b[i]] = true; ++ans; } } printf("%d\n", ans); } return 0;}
718 - E -
题目大意
思路 -
代码
- Codeforces Round-#373 (Div. 2 && Div. 1) [Codeforces719 && 718]
- Codeforces Round #167 (Div. 2 && Div.1)
- Codeforces Round #185 (Div. 1) && (Div. 2)
- Codeforces Round #166 (Div. 1) && (Div. 2)
- Codeforces Round #292 (Div. 2 Div. 1)
- Codeforces Round #413(Div. 1 + Div. 2)
- Codeforces Round #373 (Div. 2)
- Codeforces Round #373 (Div. 2)
- Codeforces Round #373 (Div. 2)
- Codeforces Round #373 (Div. 1)
- Codeforces Round #373 (Div. 2) A&B
- Codeforces Round #373 (Div. 2) C 模拟
- Codeforces Round #373 (Div. 2) ADCE题解
- Codeforces Round #124 (Div. 2) (Div.1)
- Codeforces Round #215 (Div. 2) or (Div. 1)
- Codeforces Round #230 (Div. 2) C / (Div. 1) A
- Codeforces Round #230 (Div. 2) C (Div. 1)
- Codeforces Round #250 (Div. 2) && (Div. 1) D题
- 剑指offer-算法题练习:part4 重建二叉树
- 欢迎使用CSDN-markdown编辑器
- Jenkins+Gitlab搭建CI持续集成架构
- 51串口通信
- 为什么说植保无人机发展将成为刚性需求?
- Codeforces Round-#373 (Div. 2 && Div. 1) [Codeforces719 && 718]
- Android Studio JNI 开发简单案例
- ifconfig命令
- HDU3461-Code Lock
- Java文件IO操作应该抛弃File拥抱Paths和Files
- Runtime Error:[ERROR] A Not allowed system call
- 通信信号与系统分析(二)
- 利用wireshark破解网站密码
- JAVA JDK 简单下载说明