• 青岛理工大学第五届ACM交流赛 部分题解


    A:后缀维护si*pi的最小值,查询的时候二分,判断后缀和当前两个部分就行。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 typedef long long LL;
     5 const int maxn = 100100;
     6 int n, m;
     7 LL s[maxn], p[maxn];
     8 LL suf[maxn];
     9  
    10 int main() {
    11     // freopen("in", "r", stdin);
    12     int T;
    13     LL q;
    14     scanf("%d", &T);
    15     while(T--) {
    16         scanf("%d%d",&n,&m);
    17         memset(suf, 0, sizeof(suf));
    18         for(int i = 0; i < n; i++) scanf("%lld%lld",&s[i],&p[i]);
    19         suf[n-1] = s[n-1] * p[n-1];
    20         for(int i = n - 2; i >= 0; i--) suf[i] = min(suf[i+1], s[i]*p[i]);
    21         s[n] = 100000000000000LL; suf[n] = 100000000000000LL;
    22         while(m--) {
    23             scanf("%lld", &q);
    24             int pos = lower_bound(s, s+n+1, q) - s;
    25             // if(s[pos] == q) printf("%lld
    ", q*p[pos]);
    26             if(pos == n) printf("%lld
    ", q*p[n-1]);
    27             else printf("%lld
    ", min(suf[pos], q*p[pos-1]));
    28         }
    29     }
    30     return 0;
    31 }

    B:先离散化找出所有内容的种类,之后尺取卡出最小页数。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 const int maxn = 1001000;
     5 int n, m, rl, rr;
     6 int h[maxn], p[maxn];
     7 int vis[maxn];
     8 int cnt, ret;
     9  
    10 int id(int x) {
    11     return lower_bound(h, h+m, x) - h;
    12 }
    13  
    14 int main() {
    15     // freopen("in", "r", stdin);
    16     while(~scanf("%d", &n)) {
    17         for(int i = 0; i < n; i++) {
    18             scanf("%d", &p[i]);
    19             h[i] = p[i];
    20         }
    21         sort(h,  h+n); m = unique(h, h+n) - h;
    22         memset(vis, 0, sizeof(vis));
    23         cnt = 0; ret = n; rl = 0, rr = n - 1;
    24         int lo = 0, hi = 0;
    25         while(lo < n) {
    26             while(hi < n && cnt < m) {
    27                 int idx = id(p[hi++]);
    28                 if(!vis[idx]) cnt++;
    29                 vis[idx]++;
    30             }
    31             if(cnt < m) break;
    32             if(ret > hi - lo && cnt == m) {
    33                 ret = hi - lo;
    34                 rl = lo, rr = hi - 1;
    35             }
    36             // printf("%d %d
    ", lo, hi);
    37             int idx = id(p[lo++]);
    38             vis[idx]--;
    39             if(vis[idx] == 0) cnt--;
    40             if(lo >= n) break;
    41         }
    42         printf("%d
    ", ret);
    43         printf("%d %d
    ", rl, rr);
    44     }
    45     return 0;
    46 }

    C:水题…

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 100100;
     5 int n;
     6 int a[maxn], b[maxn];
     7 
     8 int main() {
     9     // freopen("in", "r", stdin);
    10     int T;
    11     scanf("%d", &T);
    12     while(T--) {
    13         scanf("%d", &n);
    14         int x = 0, y = 0;
    15         for(int i = 1; i <= n; i++) {
    16             scanf("%d%d",&a[i],&b[i]);
    17         }
    18         sort(a+1, a+n+1);
    19         sort(b+1, b+n+1);
    20         for(int i = 1; i <= n; i++) {
    21             if(a[i] > b[i]) x += 2;
    22             else if(a[i] == b[i]) x++, y++;
    23             else y += 2;
    24         }
    25         if(x > y) puts("Winjourn");
    26         else if(x == y) puts("Tie");
    27         else puts("Never_Sorry");
    28     }
    29     return 0;
    30 }

    D:数位DP,dp(l,cnt)统计长度为l到时候1的个数为cnt的整数。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 typedef long long LL;
     5 const int maxn = 22;
     6 int digit[maxn];
     7 LL dp[maxn][maxn];
     8 LL n;
     9  
    10 LL dfs(int l, int cnt, bool flag) {
    11     if(l == 0) return cnt;
    12     if(!flag && ~dp[l][cnt]) return dp[l][cnt];
    13     int pos = flag ? digit[l] : 9;
    14     LL ret = 0;
    15     for(int i = 0; i <= pos; i++) {
    16         ret += dfs(l-1, cnt+(i==1), flag&&(pos==i));
    17     }
    18     if(!flag) dp[l][cnt] = ret;
    19     return ret;
    20 }
    21  
    22 LL f(LL x) {
    23     int pos = 0;
    24     while(x) {
    25         digit[++pos] = x % 10;
    26         x /= 10;
    27     }
    28     return dfs(pos, 0, true);
    29 }
    30  
    31 int main() {
    32     // freopen("in", "r", stdin);
    33     int _ = 1;
    34     memset(dp, -1, sizeof(dp));
    35     while(~scanf("%lld", &n)) {
    36         printf("Case %d:%lld
    ", _++, f(n));
    37     }
    38     return 0;
    39 }

    E:模拟,如果循环节正好长度为50的话,就不要打省略号了。。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 vector<int> t1, t2;
     5 map<int, int> id;
     6 int a, b;
     7  
     8 void f(int a, int b) {
     9     id.clear();
    10     t1.clear(); t2.clear();
    11     int p = -1;
    12     while(1) {
    13         t1.push_back(a/b);
    14         int x = a % b;
    15         if(x == 0) break;
    16         if(id.find(x) == id.end()) {
    17             id[x] = t2.size();
    18             t2.push_back(x);
    19         }
    20         else {
    21             p = id[x];
    22             break;
    23         }
    24         a = x * 10;
    25     }
    26     if(t1.size() == 0) while(1);
    27     printf("%d.", t1[0]);
    28     bool flag = 0;
    29     bool plusflag = 0;
    30     int cnt = 0;
    31     for(int i = 1; i < t1.size(); i++) {
    32         if(cnt >= 50) {
    33             plusflag = 1;
    34             break;
    35         }
    36         if(i == p + 1) {
    37             printf("(");
    38             flag = 1;
    39         }
    40         printf("%d", t1[i]);
    41         if(flag) cnt++;
    42     }
    43     if(plusflag) printf("...");
    44     if(p >= 0) {
    45         if(flag) printf(")
    ");
    46         printf("%d
    ", t1.size()-p-1);
    47     }
    48     else {
    49         printf("(0)
    ");
    50         printf("1
    ");
    51     }
    52 }
    53  
    54 int main() {
    55     // freopen("in", "r", stdin);
    56     // freopen("out", "w", stdout);
    57     int _ = 1;
    58     while(~scanf("%d%d",&a,&b)) {
    59         printf("Case %d:
    %d/%d=", _++, a, b);
    60         if(a % b == 0) printf("%d.(0)
    1
    ", a / b);
    61         else f(a, b);
    62     }
    63     return 0;
    64 }

    F:好麻烦的计算几何,感觉要先卡出封闭图形,之后找到所有的矩形。然后看看能放的最大圆。

    G:对整个数组排序后二分答案,贪心地从左到右选取数字,保证相邻两个数的差不小于二分出来的值,判断是否满足大于等于k个。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 const int maxn = 100100;
     5 int n, k;
     6 int a[maxn], s[maxn];
     7 int ret;
     8  
     9 bool ok(int dis) {
    10     int i = 2, p = 1;
    11     int cnt = 0;
    12     while(i <= n) {
    13         if(a[i] - a[p] >= dis) {
    14             p = i; i++;
    15             cnt++;
    16         }
    17         else i++;
    18     }
    19     return cnt + 1 >= k;
    20 }
    21  
    22 int main() {
    23     // freopen("in", "r", stdin);
    24     while(~scanf("%d%d",&n,&k)) {
    25         memset(s, 0, sizeof(s));
    26         for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    27         sort(a+1, a+n+1);
    28         ret = a[n] - a[1];
    29         int lo = 0, hi = a[n];
    30         while(lo <= hi) {
    31             int mid = (lo + hi) >> 1;
    32             if(ok(mid)) {
    33                 ret = mid;
    34                 lo = mid + 1;
    35             }
    36             else hi = mid - 1;
    37         }
    38         printf("%d
    ", ret);
    39     }
    40     return 0;
    41 }

    H:像是需要用启发式搜索将整座附近的点处理出来一个优先值,顺着第一条路走,最后回来。(后来有巨巨说是BFS)

    I:枚举a,b字符串子串的起始,扫描对应位,如果不相同则替换至相同,最多k次操作。贪心地将替换操作放到前面,如果不能替换则break更新ret。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <string>
     6 #include <map>
     7 using namespace std;
     8 
     9 const int maxn = 550;
    10 int n, m, k;
    11 char a[maxn], b[maxn];
    12 
    13 int main() {
    14     // freopen("in" ,"r", stdin);
    15     while(~scanf("%d", &k)) {
    16         scanf("%s%s",a,b);
    17         n = strlen(a); m = strlen(b);
    18         int ret = 0;
    19         for(int i = 0; i < n; i++) {
    20             for(int j = 0; j < m; j++) {
    21                 int cnt = 0, tmp = 0;
    22                 for(int aa = i, bb = j; aa < n && bb < m; aa++, bb++) {
    23                     if(a[aa] == b[bb]) tmp++;
    24                     else {
    25                         if(cnt < k) tmp++, cnt++;
    26                         else break;
    27                     }
    28                 }
    29                 ret = max(ret, tmp);
    30             }
    31         }
    32         printf("%d
    ", ret);
    33     }
    34     return 0;
    35 }

    J:f(i,j)表示和为i,用j个数字组成的方案数,转移方程f(i,j)=f(i-p,j-1),p取1~4,会爆LL所以用double存了f。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 typedef long long LL;
     5 const int maxn = 111;
     6 const int maxm = 666;
     7 int n, m;
     8 double f[maxn][maxm];
     9  
    10 int main() {
    11     // freopen("in", "r", stdin);
    12     memset(f, 0, sizeof(f));
    13     f[1][1] = 1.0; f[1][2] = 1.0; f[1][3] = 1.0; f[1][4] = 1.0;
    14     for(int i = 2; i < maxn; i++) {
    15         for(int j = 1; j < maxm; j++) {
    16             for(int k = 1; k <= 4; k++) {
    17                 if(k >= j) continue;
    18                 f[i][j] += f[i-1][j-k];
    19             }
    20         }
    21     }
    22     while(~scanf("%d%d",&n,&m)) {
    23         printf("%.4lf
    ", f[n][m]/pow(4,n));
    24     }
    25     return 0;
    26 }

    K:最后的情形无非是两种,一种是wywy..,另一种是ywyw..。整个串长度如果是奇数那么是无法围成要求的项链的;之后判断当前情况和上述哪种情况最近,然后分别找w和y错位的数量,先交换,再修改,min(w,y)+(max(w,y)-min(w,y))=max(w,y)即为答案。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 100100;
     5 char s[maxn], t[2][maxn];
     6 int n;
     7 
     8 int main() {
     9     // freopen("in", "r", stdin);
    10     memset(t, 0, sizeof(t));
    11     for(int i = 0; i < maxn; i++) {
    12         if(i % 2 == 0) {
    13             t[0][i] = 'w', t[1][i] = 'y';
    14         }
    15         else {
    16             t[0][i] = 'y', t[1][i] = 'w';
    17         }
    18     }
    19     while(~scanf("%d", &n)) {
    20         scanf("%s", s);
    21         if(n & 1) {
    22             puts("What a pity!");
    23             continue;
    24         }
    25         int a = 0, b = 0;
    26         for(int i = 0; i < n; i++) {
    27             if(s[i] != t[0][i]) a++;
    28             if(s[i] != t[1][i]) b++;
    29         }
    30         if(a < b) {
    31             int w = 0, y = 0;
    32             for(int i = 0; i < n; i++) {
    33                 if(s[i] != t[0][i]) {
    34                     if(s[i] == 'w') w++;
    35                     else y++;
    36                 }
    37             }
    38             printf("%d
    ", max(w, y));
    39         }
    40         else {
    41             int w = 0, y = 0;
    42             for(int i = 0; i < n; i++) {
    43                 if(s[i] != t[1][i]) {
    44                     if(s[i] == 'w') w++;
    45                     else y++;
    46                 }
    47             }
    48             printf("%d
    ", max(w, y));
    49         }
    50     }
    51     return 0;
    52 }

    L:不会…

  • 相关阅读:
    Hadoop集群安装
    Oracle ORA01555(快照过旧)
    selenium+java+testng+ant环境搭建
    selenium ssl
    watir识别IE版本号
    ruby and watir中timeout类的用法
    使用TestNGxslt
    ruby system用法
    IE6下调用inetcpl.cpl清除COOKIE的方法
    Shell实例:字符串操作 逻辑判断
  • 原文地址:https://www.cnblogs.com/kirai/p/6105069.html
Copyright © 2020-2023  润新知