[CCPC2017]湘潭邀请赛

题目链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/index/p/14/

D.模拟,按照原图每一个字符变成一个a*b的矩阵构造新矩阵。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 111;
 5 int n, m, a, b;
 6 char G[maxn][maxn];
 7 char GG[maxn][maxn];
 8 
 9 
10 int main() {
11     // freopen("in", "r", stdin);
12     while(~scanf("%d%d%d%d",&n,&m,&a,&b)) {
13         memset(GG, 0, sizeof(GG));
14         for(int i = 1; i <= n; i++) scanf("%s", G[i]+1);
15         for(int i = 1; i <= n; i++) {
16             for(int j = 1; j <= m; j++) {
17                 for(int ii = 1; ii <= a; ii++) {
18                     for(int jj = 1; jj <= b; jj++) {
19                         GG[(i-1)*a+ii][(j-1)*b+jj] = G[i][j];
20                     }
21                 }
22             }
23         }
24         for(int i = 1; i <= n*a; i++) printf("%s\n", GG[i]+1);
25     }
26 }

 

E.由于选取的区间点l,r都是不重复的,那么可以将整个问题描述为前缀和取2*m个点,每个点都不重复。

对整个数列排序,从两头取就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 100100;
 6 LL a[maxn], s[maxn];
 7 int n, m, c;
 8 
 9 int main() {
10     // freopen("in", "r", stdin);
11     while(~scanf("%d%d%d",&n,&m,&c)) {
12         memset(s, 0, sizeof(s));
13         for(int i = 1; i <= n; i++) {
14             scanf("%I64d", &a[i]);
15             s[i] = s[i-1] + a[i];
16         }
17         sort(s, s+n+1);
18         LL ret = 0;
19         LL tmp = 0;
20         int lo = 0, hi = n;
21         for(int i = 1; i <= m; i++) {
22             tmp += abs(s[hi]-s[lo]) - c;
23             hi--; lo++;
24             ret = max(ret, tmp);
25         }
26         printf("%I64d\n", ret);
27     }
28     return 0;
29 }

 

H.先用djikstra求出这棵树上的树直径,两个端点的再向其余边,最大的值加入到mst的权值中就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 typedef pair<LL, LL> pii;
 6 typedef struct Edge { LL v, w, next; }Edge;
 7 const LL maxn = 100100;
 8 LL n, hcnt;
 9 LL head[maxn];
10 Edge edge[maxn<<1];
11 LL d[2][maxn];
12 
13 void adde(LL u, LL v, LL w) {
14     edge[hcnt].v = v, edge[hcnt].w = w;
15     edge[hcnt].next = head[u]; head[u] = hcnt++;
16 }
17 
18 LL dij(LL id, LL u) {
19     memset(d[id], -1, sizeof(d[id]));
20     priority_queue<pii> pq;
21     pq.push(pii(0, u)); d[id][u] = 0;
22     while(!pq.empty()) {
23         pii tmp = pq.top(); pq.pop();
24         LL pw = tmp.first;
25         u = tmp.second;
26         for(LL i = head[u]; ~i; i=edge[i].next) {
27             LL v = edge[i].v, w = edge[i].w;
28             if(d[id][u] < pw) continue;
29             if(d[id][v] == -1 || d[id][v] > d[id][u] + w) {
30                 d[id][v] = d[id][u] + w;
31                 pq.push(pii(d[id][v], v));
32             }
33         }
34     }
35     LL w = 0;
36     for(LL i = 1; i <= n; i++) {
37         if(w < d[id][i]) {
38             w = d[id][i]; u = i;
39         }
40     }
41     return u;
42 }
43 
44 
45 int main() {
46     // freopen("in", "r", stdin);
47     LL u, v, w;
48     while(~scanf("%I64d", &n)) {
49         hcnt = 0;
50         memset(head, -1, sizeof(head));
51         for(LL i = 0; i < n - 1; i++) {
52             scanf("%I64d%I64d%I64d",&u,&v,&w);
53             adde(u, v, w); adde(v, u, w);
54         }
55         LL lo = dij(0, 1);
56         LL hi = dij(1, lo);
57         dij(0, hi);
58         LL ret = d[0][lo];
59         for(LL i = 1; i <= n; i++) {
60             if(i == lo || i == hi) continue;
61             ret += max(d[0][i], d[1][i]);
62         }
63         printf("%I64d\n", ret);
64     }
65 }

 

I.简单推下会发现整个式子表示的是一个数列上选取两个点,求两个点的最小间隔。最小间隔是gcd(n,m),那么选中间的位置就会使式子最小。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 111;
 6 LL n, m;
 7 LL gcd(LL x, LL y) {
 8     return y == 0 ? x : gcd(y, x % y);
 9 }
10 
11 int main() {
12     // freopen("in", "r", stdin);
13     while(cin >> n >> m) {
14         LL a = gcd(n, m);
15         LL b = 2 * n * m;
16         LL g = gcd(a, b);
17         a /= g, b /= g;
18         cout << a << "/" << b << endl;
19     }
20 }

 

A.相当于求伴随矩阵的第一列,用高斯消元求出矩阵的逆,输出第一行。

板子挂了啊。

posted @ 2017-05-16 20:03  Kirai  阅读(587)  评论(3编辑  收藏  举报