zoukankan      html  css  js  c++  java
  • 2016-2017 ACM-ICPC CHINA-Final Solution

    Problem A. Number Theory Problem

    Solved.

    水。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1e5 + 10;
     6 
     7 typedef long long ll;
     8 
     9 int n;
    10 ll arr[maxn], ans[maxn];
    11 
    12 void Init()
    13 {
    14     arr[0] = 1;
    15     for(int i = 1; i <= maxn; ++i)
    16     {
    17         arr[i] = (arr[i - 1] * 2) % 7;
    18         ans[i] = ans[i - 1];
    19         if(arr[i] == 1) ans[i]++;    
    20     }
    21 }
    22 
    23 int main()
    24 {
    25     Init();
    26     int t;
    27     scanf("%d",&t);
    28     for(int cas = 1; cas <= t; ++cas)
    29     {
    30         scanf("%d", &n);
    31         printf("Case #%d: %lld
    ", cas, ans[n]);
    32     }
    33     return 0;
    34 }
    View Code

    Problem B. Hemi Palindrome

    Unsolved.

    题意:

    定义$Hemi Palindrome$ 为去掉所有奇数位上的数字后是回文串或者去掉所有偶数位上的数是回文串,给出一个长度$N$

    构造一个字典序最小的$Hemi Palindrome$

    Problem C. Mr. Panda and Strips

    Upsolved.

    题意:

    选择序列中两段不相交的连续区间,要求这两段区间并没有重复数字,求最长长度。

    思路:

    双指针枚举第一个区间,然后再左段和右段再双指针枚举最长的合并区间

    我们考虑双指针扩展右指针的过程中,也可以更新答案

    但是对于已经在前一个左指针上扩展过的,就没有必要扩展了。

    .....L......R........

    我们考虑枚举的时候是这样的

    那么L.......R 这一段没有必要再检查是否有更大的答案,因为如果有,那么必然是L - 1........R 是更大的

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 1010
     5 #define M 100010
     6 int t, n, a[N]; 
     7 int vis[M][2];
     8 
     9 int solve(int ql, int qr)
    10 {
    11     int res = 0;
    12     for (int i = ql, r = ql - 1; i <= qr; ++i)
    13     {
    14         if (r < i) r = i - 1; 
    15         while (r < qr && !vis[a[r + 1]][0] && !vis[a[r + 1]][1])
    16         {
    17             ++r;
    18             vis[a[r]][1] = 1;
    19         }
    20         res = max(res, r - i + 1); 
    21         vis[a[i]][1] = 0; 
    22     }
    23     return res;
    24 }
    25 
    26 int main()
    27 {
    28     scanf("%d", &t);
    29     for (int kase = 1; kase <= t; ++kase)
    30     {
    31         printf("Case #%d: ", kase);
    32         scanf("%d", &n);
    33         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    34         memset(vis, 0, sizeof vis);
    35         int res = 0;
    36         for (int i = 1, r = 0; i <= n; ++i)
    37         {
    38             while (r < n && !vis[a[r + 1]][0])
    39             {
    40                 ++r;
    41                 vis[a[r]][0] = 1;
    42                 res = max(res, r - i + 1 + max(solve(1, i - 1), solve(r + 1, n)));
    43             } 
    44             int tmp = max(solve(1, i - 1), solve(r + 1, n));
    45             res = max(res, r - i + 1 + tmp);
    46             vis[a[i]][0] = 0;
    47         }
    48         printf("%d
    ", res);
    49     }
    50     return 0;
    51 }
    View Code

    Problem D. Ice Cream Tower

    Solved.

    题意:

    要构造一个冰激凌塔,并且要求$第i层的尺寸需要 >=  第 i - 1 层的尺寸 cdot 2$

    给出n个冰激凌的尺寸,求最多构造多少个K层的塔

    思路:

    二分答案,贪心摆放。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 const int maxn = 3e5 + 10;
     7 
     8 int n, k;
     9 ll arr[maxn];
    10 ll tower[maxn];
    11 
    12 bool check(int mid)
    13 {
    14     int now = 1;
    15     for(int i = 1; i <= mid; ++i) tower[i] = arr[now++];
    16     for(int i = mid + 1; i <= mid * k; ++i)
    17     {
    18         while(now <= n && arr[now] < tower[i - mid] * 2) ++now;
    19         if(now > n) return false;
    20         tower[i] = arr[now++];
    21     }
    22     return true;
    23 }
    24 
    25 int main()
    26 {
    27     int t;
    28     scanf("%d", &t);
    29     for(int cas = 1; cas <= t; ++cas)
    30     {
    31         scanf("%d %d", &n, &k);
    32         for(int i = 1; i <= n; ++i) scanf("%lld", arr + i);
    33         sort(arr + 1, arr + 1 + n);
    34         int l = 0, r = n / k, res = 0;
    35         while(r - l >= 0)
    36         {
    37             int mid = (l + r) >> 1;
    38             if(check(mid)) 
    39             {
    40                 l = mid + 1;
    41                 res = mid;
    42             }
    43             else r = mid - 1;
    44         }
    45         printf("Case #%d: %d
    ", cas, res);
    46     }
    47     return 0;
    48 }
    View Code

    Problem E. Bet

    Solved.

    题意:

    有一家赌球公司,你要赌球,对于每一支队伍 赔率是$A_i : B_i$

    你要如何下注,使得如果有一只球队赢了,你就不会亏本,求你最多能下注的数量。

    思路:

    假设本金为1, 考虑对$第i支球队下注p_i 那么需要满足 p_i + p_i cdot frac{B_i}{A_i} > 1 $

    移项之后即为$p_i > frac{A_i}{A_i + B_i}$

    那么对所有球队按这个式子从小到大排序,取到大于一就不取了

    注意精度问题,数据保证小数点后最多三位,直接$ * 1000$

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const double eps = 1e-8;
     8 const ll MOD = 1e9 + 7;
     9 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
    10 const int INF = 0x3f3f3f3f;
    11 const int maxn = 1e5 + 10;
    12 
    13 int n;
    14 long double arr[maxn];
    15 
    16 void RUN()
    17 {
    18     int t;
    19     scanf("%d", &t);
    20     for (int cas = 1; cas <= t; ++cas)
    21     {
    22         scanf("%d", &n);
    23         for (int i = 1; i <= n; ++i)
    24         {
    25             long double ai, bi;
    26             scanf("%Lf:%Lf", &ai, &bi);
    27             ai = (int)(ai * 1000 + 0.1);
    28             bi = (int)(bi * 1000 + 0.2);
    29             arr[i] = ai / (ai + bi);
    30         }
    31         sort(arr + 1, arr + 1 + n);
    32         long double sum = 0;
    33         int cnt = 0;
    34         for (int i = 1; i <= n; ++i)
    35         {
    36             sum += arr[i];
    37             if (sum >= (long double)1.0) break;
    38             cnt++;
    39         }
    40         printf("Case #%d: %d
    ", cas, cnt);
    41     }
    42 }
    43 
    44 int main()
    45 {
    46 #ifdef LOCAL_JUDGE
    47     freopen("Text.txt", "r", stdin);
    48 #endif // LOCAL_JUDGE
    49 
    50     RUN();
    51 
    52 #ifdef LOCAL_JUDGE
    53     fclose(stdin);
    54 #endif // LOCAL_JUDGE
    55 
    56     return 0;
    57 }
    View Code

    Problem F. Mr. Panda and Fantastic Beasts

    Unsolved.

    Problem G. Pandaria

    Unsolved.

    Problem H. Great Cells

    Solved.

    题意:

    定义$Ag 矩阵中恰好有g个好点的方案数,定义好点为那一个点所在的行和列它最大,严格最大$

    求$sum_{i = 0}^{i = n * m} (g + 1) * A_g$

    思路:

    考虑将式子拆成

    $sum_{g = 0}^{g = n * m} g * A_g + sum_{g = 0}^{g = n * m}A_g$

    显然 右边的项的答案就是$k^{n * m}$

    再考虑左边

    如果我把式子 除以$sum_{g = 1}^{g = n * m} A_g$ 

    那么整个式子表达的含义即$g$  的数学期望

    我们再考虑用另一种方法求数学期望

    $E cdot sum_{g = 1}^{g = n * m} A_g = n * m * sum_{i = 2}^{i = k} (i - 1) ^ {n + m - 2} cdot k ^{(n - 1) * (m - 1)}$

    含义是 令$i为好点的值,有多少种方案,那么显然,任意一个点都可以是好点,那么同行同列的取值为[1, i - 1]$

    $其它格子的取值随意$

    那么等式右边算出来的即是$所有g的总和$

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const ll MOD = 1e9 + 7;
     8 
     9 ll qpow(ll x, ll n)
    10 {
    11     ll res = 1;
    12     while(n)
    13     {
    14         if(n & 1) res = res * x % MOD;
    15         x = x * x % MOD;
    16         n >>= 1;
    17     }
    18     return res;
    19 }
    20 
    21 int t;
    22 int n, m, k;
    23 
    24 int main()
    25 {
    26     scanf("%d", &t);
    27     for(int cas = 1; cas <= t; ++cas)
    28     {
    29         scanf("%d %d %d", &n, &m, &k);
    30         ll ans = 0;
    31         for(int i = 2; i <= k; ++i)
    32         {
    33             ans = (ans + n * m % MOD * qpow(i - 1, n + m - 2) % MOD * qpow(k, (n - 1) * (m - 1)) % MOD) % MOD;
    34         }
    35         ans = (ans + qpow(k, n * m)) % MOD;
    36         printf("Case #%d: %lld
    ", cas, ans);
    37     }
    38     return 0;
    39 }
    View Code

    Problem I. Cherry Pick

    Unsolved.

    Problem J. Mr.Panda and TubeMaster

    Unsolved.

    Problem K. Justice Rains From Above

    Unsolved.

    Problem L. World Cup

    Solved.

    水。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int arr[3] = {3, 1, 0};
     6 int brr[3] = {0, 1, 3};
     7 int ans[10][10][10][10];
     8 
     9 void Init()
    10 {
    11     for(int i1 = 0; i1 < 3; ++i1)
    12     {
    13         for(int i2 = 0; i2 < 3; ++i2)
    14         {
    15             for(int i3 = 0; i3 < 3; ++i3)
    16             {
    17                 for(int i4 = 0; i4 < 3; ++i4)
    18                 {
    19                     for(int i5 = 0; i5 < 3; ++i5)
    20                     {
    21                         for(int i6 = 0; i6 < 3; ++i6)
    22                         {
    23                             int a = arr[i1] + arr[i2] + arr[i3];
    24                             int b = brr[i1] + arr[i4] + arr[i5];
    25                             int c = brr[i2] + brr[i4] + arr[i6];
    26                             int d = brr[i3] + brr[i5] + brr[i6];
    27                             ans[a][b][c][d]++;
    28                         }
    29                     }
    30                 }
    31             }
    32         }
    33     }
    34 }
    35 
    36 int a, b, c, d;
    37 
    38 int main()
    39 {
    40     Init();
    41     int t;
    42     scanf("%d", &t);
    43     for(int cas = 1; cas <= t; ++cas)
    44     {
    45         scanf("%d %d %d %d",&a, &b, &c, &d);
    46         printf("Case #%d: ", cas);
    47         if(a > 9 || b > 9 || c > 9 || d > 9) puts("Wrong Scoreboard");
    48         else if(ans[a][b][c][d] > 1) puts("No");
    49         else if(ans[a][b][c][d]) puts("Yes");
    50         else puts("Wrong Scoreboard");
    51     }
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    48、Windows驱动程序模型笔记(六),同步
    44、Windows驱动程序模型笔记(二)
    JavaP:对象创建
    JavaP:继承和多态【只有提纲】
    ASP.NET MVC:一个简单MVC示例
    JavaP: 2、类和对象
    ASP.NET MVC:解析 MVC+ADO.NET Entity(实体类)
    Oracle: 一、Oracle简介,安装,基本使用,建表增删改查,数据类型及常用命令
    JavaP:面向对象编程
    ASP.NET: PagedDataSource
  • 原文地址:https://www.cnblogs.com/Dup4/p/9975047.html
Copyright © 2011-2022 走看看