牛客小白月赛16

链接:https://ac.nowcoder.com/acm/contest/949#question

A:

思路:博弈题,写几个推一推就发现除了 n == 1 shi 必胜。

 1 #include
 2 using namespace std;
 3 int main()
 4 {
 5     std::ios::sync_with_stdio(false);
 6     int n;
 7     cin >> n;
 8     if(n == 1) cout << "Yang" << endl;
 9     else cout << "Shi" << endl;
10     return 0;
11 }
View Code

 

B:

思路:暴力推出杨辉三角,然后每行数字加起来暴力求和。

 1 #include
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e3 + 5;
 5 const int mod = 1e9 + 7;
 6 int n, m;
 7 ll a[maxn][maxn];
 8 ll ans[maxn];
 9 void init(int n)
10 {
11     for(int i = 1;i <= n;i++)
12         a[i][1] = a[i][i] = i % mod;
13     for(int i = 1;i <= n;i++)
14         for(int j = 2;j < i;j++)
15             a[i][j] = (a[i - 1][j] % mod + a[i - 1][j - 1] % mod)%mod;
16     for(int i = 1;i <= n;i++)
17         for(int j = 1;j <= i;j++)
18             ans[i] += a[i][j] % mod;
19 }
20 int main()
21 {
22     std::ios::sync_with_stdio(false);
23     cin >> n >> m;
24     int a, b;
25     init(n);
26     while(m--){
27         cin >> a >> b;
28         ll sum = 0;
29         for(int i = a;i <= b;i++) sum += ans[i] % mod;
30         cout << sum % mod << endl;
31     }
32     return 0;
33 }
View Code

 

C:

思路:暴力模拟。

 1 #include
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e3 + 5;
 5 int n, m;
 6 int a[maxn];
 7 int dfs(int x)
 8 {
 9     int ans = 0;
10     bool flag = true;
11     for(int i = 0;i < n;i++)
12     {
13         if(a[i] > x){
14             if(flag) ans++,flag = false;
15         }
16         else flag = true;
17     }
18     return ans;
19 }
20 int main()
21 {
22     std::ios::sync_with_stdio(false);
23     cin >> n >> m;
24     for(int i = 0;i < n;i++) cin >> a[i];
25     int h;
26     while(m--)
27     {
28         cin >> h;
29         cout << dfs(h) << endl;
30     }
31     return 0;
32 }
View Code

 

D;

思路:用前缀和表示区间的元素和,将所有前缀和递减排列使其单调。每次可以二分出当前最长区间,不断更新答案即可。

 1 #include
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 2e6 + 5;
 5 int n;
 6 int a[maxn];
 7 int main()
 8 {
 9     std::ios::sync_with_stdio(false);
10     int n;
11     cin >> n;
12     int ans = 0;
13     int sum = 0;
14     int x;
15     for(int i = 1;i <= n;i++){
16         cin >> x, sum += x;
17         a[i] = min(a[i - 1], sum); //最小前缀和
18         int l = 0, r = i - 1;
19         while(l <= r)
20         {
21             int mid = (r + l) >> 1;
22             if(a[mid] < sum) r = mid - 1;
23             else l = mid + 1;
24         }
25         ans = max(ans, i - r - 1);
26     }
27     cout << ans << endl;
28     return 0;
29 }
View Code

E:

思路:暴力dfs所有状态,set去重。

 1 #include
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 100;
 5 int n;
 6 int mp[maxn][maxn];
 7 set<int> st;
 8 int dx[2] = {0, 1};
 9 int dy[2] = {1, 0};
10 bool check(int x, int y)
11 {
12     if(x >= 1 && x <= n && y >= 1 && y <= n) return true;
13     else return false;
14 }
15 void dfs(int x, int y, int sum)
16 {
17     if(x == n && y == n){ st.insert(sum); return;}
18     for(int i = 0;i < 2;i++){
19         int nx = x + dx[i];
20         int ny = y + dy[i];
21         if(check(nx, ny)) dfs(nx, ny, sum + mp[nx][ny]);
22     }
23 }
24 int main()
25 {
26     std::ios::sync_with_stdio(false);
27     cin >> n;
28     for(int i = 1;i <= n;i++)
29         for(int j = 1;j <= n;j++)
30             cin >> mp[i][j];
31     dfs(1,1,mp[1][1]);
32     cout << st.size() << endl;
33     return 0;
34 }
View Code

 

F:

思路:按 a的大小从大到小排序,然后依次对b大于它的编号,不断更新b.

 1 #include
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5 + 7;
 5 struct node{
 6     int x, id;
 7 };
 8 node a[maxn],b[maxn];
 9 bool cmp(const node &a, const node &b){
10     return a.x > b.x;
11 }
12 int ans[maxn];
13 int main()
14 {
15     std::ios::sync_with_stdio(false);
16     int n;
17     cin >> n;
18     for(int i = 0;i < n;i++)
19     {
20         cin >> a[i].x >> b[i].x;
21         a[i].id = i;
22     }
23     sort(a, a + n, cmp);
24     int cnt = 0;
25     for(int i = 0;i < n;i++)
26     {
27         if( !ans[a[i].id])
28         {
29             ans[a[i].id] = ++cnt;
30             int now = b[a[i].id].x;
31             for(int j = i + 1;j < n;j++)
32             {
33                 if(b[a[j].id].x > now && !ans[a[j].id])
34                 {
35                     ans[a[j].id] = cnt;
36                     now = b[a[j].id].x;
37                 }
38             }
39         }
40     }
41     for(int i = 0;i < n;i++)
42     {
43         cout << ans[i] << endl;
44     }
45     return 0;
46 }
View Code

 

G:

思路:推公式即可。

 1 #include
 2 using namespace std;
 3 const double pi = acos(-1.0);
 4 int main()
 5 {
 6     double n;
 7     scanf("%lf", &n);
 8     printf("%.3f\n", n * n / pi / 2.0);
 9     return 0;
10 }
View Code

 

H:

思路:参考https://www.cnblogs.com/wushengyang/p/11192089.html。俩小时学了个线段树查区间gcd。

 

 1 #include
 2 using namespace std;
 3 #define ls rt << 1
 4 #define rs rt << 1 | 1
 5 #define lson l, m, rt << 1
 6 #define rson m + 1, r, rt << 1 | 1
 7 #define lr2 (l + r) >> 1
 8 const int maxn = 1e5+5;
 9 int sum[maxn << 2], gcd[maxn << 2], Max[maxn << 2];
10 int a[maxn];
11 void pushup(int rt)
12 {
13     gcd[rt] = __gcd(gcd[ls], gcd[rs]);
14     sum[rt] = sum[ls] + sum[rs];
15     Max[rt] = max(Max[ls], Max[rs]);
16 }
17 void build(int l, int r, int rt)
18 {
19     if(l == r){
20         sum[rt] = a[l];
21         Max[rt] = gcd[rt] = abs(a[l]);
22         return ;
23     }
24     int m = lr2;
25     build(lson);
26     build(rson);
27     pushup(rt);
28 }
29 void update(int p, int v, int l, int r, int rt)
30 {
31     if(l == r)
32     {
33         a[l] += v;
34         sum[rt] = a[l];
35         Max[rt] = gcd[rt] = max(a[l], -a[l]);
36         return;
37     }
38     int m = lr2;
39     if(p <= m) update(p, v, lson);
40     else update(p, v, rson);
41     pushup(rt);
42 }
43 int query_sum(int a, int b, int l, int r, int rt)
44 {
45     if(a <= l && b >= r) return sum[rt];
46     int ans = 0;
47     int m = lr2;
48     if(a <= m) ans += query_sum(a, b, lson);
49     if(b > m) ans += query_sum(a, b, rson);
50     return  ans;
51 }
52 int query_Max(int a, int b, int l, int r, int rt)
53 {
54     if(a <= l && b >= r) return abs(Max[rt]);
55     int ans = 0;
56     int m = lr2;
57     if(a <= m) ans = max(ans, query_Max(a, b, lson));
58     if(b > m) ans = max(ans, query_Max(a, b, rson));
59     return  ans;
60 }
61 int query_gcd(int a, int b, int l, int r, int rt)
62 {
63     if(a <= l && b >= r) return gcd[rt];
64     int ans = 0;
65     int m = lr2;
66     if(a <= m) ans = __gcd(ans,query_gcd(a, b, lson));
67     if(b > m) ans = __gcd(ans,query_gcd(a, b, rson));
68     return  ans;
69 }
70 int main()
71 {
72     std::ios::sync_with_stdio(false);
73     int n, q;
74     cin >> n >> q;
75     int c, l, r, x;
76     for(int i = 1;i <= n;i++) cin >> a[i];
77     for(int i = n;i;i--) a[i] -= a[i - 1];
78     build(1, n, 1);
79     while(q--)
80     {
81         cin >> c >> l >> r;
82         if(c == 1){
83             cin >> x;
84             update(l, x, 1, n, 1);
85             if(r < n) update(r + 1, -x, 1, n, 1);
86         }
87         else if(c == 2){
88             if(l == r) cout << 0 <<endl;
89             else cout << query_Max(l + 1, r, 1, n, 1) << endl;
90         }
91         else{
92             int t = abs(query_sum(1, l, 1, n, 1));
93             if(l == r) cout << t << endl;
94             else cout << __gcd(t, query_gcd(l + 1, r, 1, n, 1)) << endl;
95         }
96 
97     }
98     return 0;
99 }
View Code

 

I:

思路:期望dp完全两眼一摸黑,完全不会。补上大佬的思路。

第一步前进的期望dp[1]是1 / a,(因为不会后退)

后面每一步前进的期望dp[i] = 1 (摇到前进) + b / a (摇到平局) + c / a * (dp[i - 1] + 1) (摇到后退,代价是摇了一下后退并且需要再上来)。

 1 #include
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e3 + 5;
 5 const int mod = 1e9 + 7;
 6 ll dp[maxn];
 7 ll quick_mod(ll a, ll b)
 8 {
 9     ll ans  = 1;
10     while(b)
11     {
12         if(b & 1) ans = ans * a % mod;
13         b >>= 1;
14         a = a * a % mod;
15     }
16     return ans;
17 }
18 ll inv(ll x)
19 {
20     return quick_mod(x, mod - 2);
21 }
22 int main()
23 {
24     ll n, a, b;
25     cin >> n >> a >> b;
26     ll ans = dp[1] = inv(a);
27     ll c = ((1LL - a - b) % mod + mod) % mod;
28     for(int i = 2; i < n; i ++){
29         dp[i] = 1LL + c * inv(a) % mod * (1LL + dp[i - 1]) % mod + b * inv(a) % mod;
30         dp[i] %= mod;
31         ans = (ans + dp[i]) % mod;
32     }
33     cout << ans % mod << endl;
34     return 0;
35 }
View Code

 

J:

思路:K层图模板题,将1 - n编号的点作为中转点,中转点下车不收费,上车收费,从 n + 1开始依次记录与中转点的关系并且添加到下一站的边,最后跑dijkstra求最短路即可。

 1 #include
 2 using namespace std;
 3 const int maxn = 2e5+ 5;
 4 const int INF = 0x3f3f3f3f;
 5 typedef pair<int, int >P;
 6 int n, m;
 7 struct node{
 8     int to, cost;
 9 };
10 node es;
11 vector G[maxn];
12 int d[maxn];
13 void dijkstra(int s)
14 {
15     priority_queue, greater

> que; 16 memset(d, INF, sizeof(d)); 17 d[s] = 0; 18 que.push(P(0,s)); 19 while(!que.empty()) 20 { 21 P now = que.top();que.pop(); 22 int v = now.second; 23 if(d[v] < now.first) continue; 24 for(int i = 0; i < G[v].size();i++) 25 { 26 node e = G[v][i]; 27 if(d[e.to] > d[v] + e.cost){ 28 d[e.to] = d[v] + e.cost; 29 que.push(P(d[e.to], e.to)); 30 } 31 } 32 } 33 } 34 void add(int a, int b, int c) 35 { 36 es.to = b; 37 es.cost = c; 38 G[a].push_back(es); 39 } 40 int main() 41 { 42 std::ios::sync_with_stdio(false); 43 int st, ed; 44 cin >> n >> m >>st >> ed; 45 int cnt = n, last; 46 for(int i = 0;i < m;i++) 47 { 48 int a, b, c, x; 49 cin >> a >> b >> c; 50 for(int j = 0;j < c;j++) 51 { 52 cin >> x; 53 add(++cnt, x, 0); 54 add(x, cnt, a); 55 if(j){ 56 add(cnt, last, b); 57 add(last, cnt, b); 58 } 59 last = cnt; 60 } 61 } 62 dijkstra(st); 63 if(d[ed] == INF){ 64 cout<< -1 << endl; 65 } 66 else cout << d[ed] << endl; 67 68 return 0; 69 }

View Code

 

转载于:https://www.cnblogs.com/Carered/p/11482667.html

你可能感兴趣的:(牛客小白月赛16)