牛客2020年七夕节比赛BCE
一道有意思的题目
https://ac.nowcoder.com/acm/contest/7009/A
B题
- 所以大于3的时候答案就是0了,那么小于三的时候,就需要特判了,而等于三的时候就需要自己一个一个算就好了
#include <iostream> #include <sstream> using namespace std; int main() { long long n,m; int t; cin >> t; while(t --) { cin >> n >> m; if(n > 3){ cout << 0 << endl; } else if(n == 3){ long long res = 1; for(long long i = 1;i <= 720;i ++) { res *= i; res %= m; } cout << res << endl; } else if(n == 1 || n == 2){ cout << n % m << endl; } else if(n == 0){ cout << 1 % m << endl; } } return 0; }
C题
- 这个题照着图画就好了
#include <iostream> #include <sstream> using namespace std; int main() { int n; cin >> n; cout << "I love U forever." << endl; int base = n; int kong = n,kong2 = n * 2 - 1; for(int i = 0;i < n;i ++) { for(int j = 0;j < kong;j ++) cout << ' '; for(int j = 0;j < base;j ++) cout << '*'; for(int j = 0;j < kong2;j ++) cout << ' '; for(int j = 0;j < base;j ++) cout << '*'; base += 2; kong -= 1; kong2 -= 2; cout << endl; } for(int i = 0;i < n * 3;i ++) { for(int j = 0;j < kong;j ++) cout << ' '; for(int j = 0;j < base;j ++) cout << '*'; for(int j = 0;j < base - 1;j ++) cout << '*'; base -= 1; kong += 1; cout << endl; } return 0; } /* I love U forever. * * 1 1 ***** *** * I love U forever. *** *** 3 5 ***** *****2 3 ******* *******1 1 ***************** *************** ************* *********** ********* ******* ***** *** * I love U forever. ** ** 2 3 **** ****1 1 *********** ********* ******* ***** *** * */
E题
- 按照题目给的公式来求取最终答案,首先我们先要算出有多少次是不挨揍的,假设c到b的距离+b到1号的距离之和为dis
- 设a到1号点的距离为dep
- if(max(dep,dis) < t),那么牛牛就算成功
- a到1号点的距离很好求,bfs或者dfs算出距离来,depth数组是记录每个点到0号点的距离
- 那么c->b->1这个怎么求呢
- 我大体分为了三种情况(可能这里有重复的情况,当时没考虑太多)
- 假设b和c的最近公共祖先为f点
- f == b ,2. f == c, 3. f != c && f != b
- 对于第一种情况那么dis就是 c -> b -> 1 ,dis也就是 depth[c] - 1(这里我设置的根节点为0号点,depth[1] = 1,depth[0] = 0)
- 对于第二种情况那么我们就需要这样走,c -> b,然后再从b -> c,然后再从c到1号点,那么dis就是 (depth[b] - depth[c]) * 2 + depth[c] - 1;
- 对于第三种情况 首先是 c -> f,然后f -> b,然后b -> 1,dis = (depth[c] - depth[f]) + (depth[b] - depth[f]) + (depth[b] - 1);
#include <iostream> #include <queue> #include <vector> #include <cstring> using namespace std; typedef long long LL; const long long mod = 1e9 + 7; const long long N = 1e6 + 10; long long fa[N][16]; long long n,m; long long depth[N]; vector<long long>v[N]; LL qpow(LL a,LL k) { LL res = 1; while(k) { if(k & 1) res = (long long)res * a % mod; a = (long long )a * a % mod; k >>= 1; } return res; } LL inv(LL x) { return qpow(x,mod - 2) % mod; } void bfs(long long root) { memset(depth,0x3f,sizeof depth); depth[root] = 1; depth[0] = 0; queue<long long>q; q.push(root); while(q.size()) { long long t = q.front();q.pop(); for(auto &x : v[t]) { if(depth[x] > depth[t] + 1) { depth[x] = depth[t] + 1; q.push(x); fa[x][0] = t; for(long long i = 1;i <= 15;i ++) { fa[x][i] = fa[fa[x][i - 1]][i - 1]; } } } } } long long lca(long long a,long long b) { if(depth[a] < depth[b]) swap(a,b); for(long long i = 15;i >= 0;i --) { if(depth[fa[a][i]] >= depth[b]) { a = fa[a][i]; } } if(a == b) return a; for(long long i = 15;i >= 0;i --) { if(fa[a][i] != fa[b][i]) { a = fa[a][i]; b = fa[b][i]; } } return fa[a][0]; } int main() { cin >> n; long long root = 1; for(long long i = 0;i < n - 1;i ++) { long long a,b; cin >> a >> b; v[a].push_back(b); v[b].push_back(a); } bfs(root); cin >> m; long long q = m; long long a,b,c,t; long long sum = 0; /* for(int i = 1;i <= n;i ++) { cout << "```" << depth[i] << endl; }*/ while(m --) { cin >> a >> b >> c >> t; long long dep = depth[a] - 1; long long f = lca(b,c); long long dis; // cout << f << endl ; if(f == b){ dis = depth[c] - 1; } else if(f == c){ dis = (depth[b] - depth[c]) * 2 + depth[c] - 1; } else{ dis = depth[c] - depth[f] + depth[b] - depth[f] + depth[b] - 1; } dep = max(dis,dep); if(dep < t){ sum ++; } // cout << dep <<' ' << dis << endl; } LL ans = sum * inv(q) % mod; cout << ans << endl; return 0; }