大学生程序设计邀请赛(华东师范大学)

比赛链接:http://acm.ecnu.edu.cn/contest/11/

 

E.水题,手工模拟下就会发现这就是在做求gcd的步骤,所以用lcm除以x就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 LL x, n;
 6 
 7 int main() {
 8     // freopen("in", "r", stdin);
 9     while(~scanf("%lld%lld",&x,&n)) {
10         for(LL i = 2; i <= n; i++) {
11             cout << x / __gcd(x, i) * i / x << endl;
12         }
13     }
14     return 0;
15 }

 

A.很烦人,因为unicode的问题,python写起来很轻松。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int maxn = 1010010;
  5 char a[maxn];
  6 
  7 int main() {
  8     // freopen("in", "r", stdin);
  9     int T, _ = 1;
 10     scanf("%d",&T);
 11     while(T--) {
 12         memset(a, 0, sizeof(a));
 13         scanf("%s",a);
 14         int len=strlen(a);
 15         if(a[len-1]>='1'&&a[len-1]<='4') {
 16             int aa=0,ee=0,ii=0,oo=0,uu=0,vv=0;
 17             printf("Case %d: ", _++);
 18             for(int i=0;i<len-1;i++) {
 19                 if(a[i]=='a')aa++;
 20                 if(a[i]=='e')ee++;
 21                 if(a[i]=='i')ii++;
 22                 if(a[i]=='o')oo++;
 23                 if(a[i]=='u')uu++;
 24                 if(a[i]=='v')vv++;
 25             }
 26             if(aa) {
 27                 for(int i=0;i<len-1;i++) {
 28                     if(a[i]=='a') {
 29                         if(a[len-1]=='1')printf("ā");
 30                         if(a[len-1]=='2')printf("á");
 31                         if(a[len-1]=='3')printf("ǎ");
 32                         if(a[len-1]=='4')printf("à");
 33                     }
 34                     else printf("%c",a[i]);
 35                 }
 36                 printf("\n");
 37             }
 38             else {
 39                 if(oo) {
 40                     for(int i=0;i<len-1;i++) {
 41                         if(a[i]=='o') {
 42                             if(a[len-1]=='1')printf("ō");
 43                             if(a[len-1]=='2')printf("ó");
 44                             if(a[len-1]=='3')printf("ǒ");
 45                             if(a[len-1]=='4')printf("ò");
 46                         }
 47                         else printf("%c",a[i]);
 48                     }
 49                 printf("\n");
 50             }
 51             else if(ee) {
 52                     for(int i=0;i<len-1;i++) {
 53                         if(a[i]=='v')a[i]='u';
 54                     }
 55                 for(int i=0;i<len-1;i++) {
 56                     if(a[i]=='e') {
 57                         if(a[len-1]=='1')printf("ē");
 58                         if(a[len-1]=='2')printf("é");
 59                         if(a[len-1]=='3')printf("ě");
 60                         if(a[len-1]=='4')printf("è");
 61                     }
 62                     else printf("%c",a[i]);
 63                 }
 64                 printf("\n");
 65             }
 66             else if(ii&&!uu) {
 67                 for(int i=0;i<len-1;i++) {
 68                     if(a[i]=='i') {
 69                         if(a[len-1]=='1')printf("ī");
 70                         if(a[len-1]=='2')printf("í");
 71                         if(a[len-1]=='3')printf("ǐ");
 72                         if(a[len-1]=='4')printf("ì");
 73                     }
 74                     else printf("%c",a[i]);
 75                 }
 76                 printf("\n");
 77             }
 78             else if(uu&&!ii) {
 79                 for(int i=0;i<len-1;i++) {
 80                     if(a[i]=='u') {
 81                         if(a[len-1]=='1')printf("ū");
 82                         if(a[len-1]=='2')printf("ú");
 83                         if(a[len-1]=='3')printf("ǔ");
 84                         if(a[len-1]=='4')printf("ù");
 85                     }
 86                 else printf("%c",a[i]);
 87                 }
 88                     printf("\n");
 89             }
 90             else if(uu&&ii) {
 91                 int post1=0;
 92                 int post2=0;
 93                 for(int i=0;i<len-1;i++)if(a[i]=='u')post1=i;
 94                 for(int i=0;i<len-1;i++)if(a[i]=='i')post2=i;
 95                 if(post1<post2) {
 96                     for(int i=0;i<len-1;i++) {
 97                         if(a[i]=='i') {
 98                             if(a[len-1]=='1')printf("ī");
 99                             if(a[len-1]=='2')printf("í");
100                             if(a[len-1]=='3')printf("ǐ");
101                             if(a[len-1]=='4')printf("ì");
102                         }
103                         else printf("%c",a[i]);
104                     }
105                     printf("\n");
106                 }
107                 else {
108                     for(int i=0;i<len-1;i++) {
109                         if(a[i]=='u') {
110                             if(a[len-1]=='1')printf("ū");
111                             if(a[len-1]=='2')printf("ú");
112                             if(a[len-1]=='3')printf("ǔ");
113                             if(a[len-1]=='4')printf("ù");
114                         }
115                         else printf("%c",a[i]);
116                     }
117                     printf("\n");
118                 }
119             }
120             else if(vv&&!ee) {
121                 for(int i=0;i<len-1;i++) {
122                     if(a[i]=='v') {
123                         if(a[len-1]=='1')printf("ǖ");
124                         if(a[len-1]=='2')printf("ǘ");
125                         if(a[len-1]=='3')printf("ǚ");
126                         if(a[len-1]=='4')printf("ǜ");
127                     }
128                     else printf("%c",a[i]);
129                 }
130                 printf("\n");
131             }
132             }
133         }
134         else printf("Case %d: %s\n",_++,a);
135     }
136 }

 

F.按照r排序,贪心从每一个需要安放灯的r到l开始放就行,这样能保证当前区间与后面的区间相交的部分最大。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef struct Node {
 5     int l, r, t;
 6 }Node;
 7 
 8 const int maxn = 1010;
 9 int n, m, k;
10 bool vis[maxn];
11 Node p[maxn];
12 
13 bool cmp(Node a, Node b) {
14     return a.r < b.r;
15 }
16 
17 int gao() {
18     int ret = 0;
19     for(int i = 0; i < m; i++) {
20         if(p[i].r - p[i].l + 1 < p[i].t) return -1;
21         int cnt = 0;
22         for(int j = p[i].l; j <= p[i].r; j++) cnt += vis[j];
23         if(cnt >= p[i].t) continue;
24         for(int j = p[i].r; j >= p[i].l; j--) {
25             if(!vis[j]) {
26                 vis[j] = 1;
27                 cnt++;
28                 ret++;
29                 if(cnt == p[i].t) break;
30             }
31         }
32     }
33     return ret;
34 }
35 
36 int main() {
37     // freopen("in", "r", stdin);
38     int T, _ = 1;
39     int l, r, t;
40     scanf("%d", &T);
41     while(T--) {
42         scanf("%d%d%d",&n,&m,&k);
43         memset(vis, 0, sizeof(vis));
44         int pos = 0;
45         for(int i = 0; i < k; i++) {
46             scanf("%d", &pos);
47             vis[pos] = 1;
48         }
49         for(int i = 0; i < m; i++) {
50             scanf("%d%d%d",&l,&r,&t);
51             p[i] = Node{l, r, t};
52         }
53         sort(p, p+m, cmp);
54         
55         printf("Case %d: %d\n", _++, gao());
56      }
57     return 0;
58 }

 

G.二分k,更新花费后最小生成树,求是否mst<=M。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 typedef struct Edge {
  5     int u, v, t, f; double cost;
  6     bool operator<(const Edge a)const {
  7         return cost < a.cost;
  8     }
  9 }Edge;
 10 
 11 const int maxn = 100100;
 12 const double eps = 1e-11;
 13 int n, m;
 14 Edge edge[maxn];
 15 int pre[maxn];
 16 double M;
 17 
 18 bool cmp(Edge a, Edge b) { return a.cost < b.cost; }
 19 
 20 int find(int x) { return x == pre[x] ? x : pre[x] = find(pre[x]); }
 21 
 22 bool ok(double k) {
 23     double cost = .0;
 24     for(int i = 1; i <= n; i++) pre[i] = i;
 25     for(int i = 1; i <= m; i++) {
 26         if(edge[i].f) edge[i].cost = edge[i].t * 1.0 *  k;
 27         else edge[i].cost = edge[i].t;
 28     }
 29     sort(edge+1, edge+m+1);
 30     for(int i = 1; i <= m; i++) {
 31         int u = edge[i].u, v = edge[i].v;
 32         int pu = find(u), pv = find(v);
 33         if(pu == pv) continue;
 34         pre[pu] = pv;
 35         cost += edge[i].cost;
 36     }
 37     return cost <= M;
 38 }
 39 
 40 inline bool scan_d(int &num) {
 41     char in;bool IsN=false;
 42     in=getchar();
 43     if(in==EOF) return false;
 44     while(in!='-'&&(in<'0'||in>'9')) in=getchar();
 45     if(in=='-'){ IsN=true;num=0;}
 46     else num=in-'0';
 47     while(in=getchar(),in>='0'&&in<='9'){
 48         num*=10,num+=in-'0';
 49     }
 50     if(IsN) num=-num;
 51     return true;
 52 }
 53 
 54 inline bool scan_lf(double &num) {
 55     char in;double Dec=0.1;
 56     bool IsN=false,IsD=false;
 57     in=getchar();
 58     if(in==EOF) return false;
 59     while(in!='-'&&in!='.'&&(in<'0'||in>'9'))
 60             in=getchar();
 61     if(in=='-'){IsN=true;num=0;}
 62     else if(in=='.'){IsD=true;num=0;}
 63     else num=in-'0';
 64     if(!IsD){
 65             while(in=getchar(),in>='0'&&in<='9'){
 66                     num*=10;num+=in-'0';}
 67     }
 68     if(in!='.'){
 69             if(IsN) num=-num;
 70             return true;
 71     }else{
 72             while(in=getchar(),in>='0'&&in<='9'){
 73                     num+=Dec*(in-'0');Dec*=0.1;
 74             }
 75     }
 76     if(IsN) num=-num;
 77     return true;
 78 }
 79 
 80 int main() {
 81     // freopen("in", "r", stdin);
 82     while(~scanf("%d",&n)) {
 83         scan_d(m);
 84         scan_lf(M);
 85         for(int i = 1; i <= m; i++) {
 86             scan_d(edge[i].u);
 87             scan_d(edge[i].v);
 88             scan_d(edge[i].t);
 89             scan_d(edge[i].f);
 90         }
 91         double lo = 1, hi = 1e15;
 92         for(int i = 0; i < 100; i++) {
 93             double mid = (lo + hi) / 2;
 94             if(ok(mid)) lo = mid;
 95             else hi = mid;
 96         }
 97         printf("%.10f\n", lo);
 98     }
 99     return 0;
100 }

 

C.n m <= 8,暴力回溯就行。注意走到一个点要让它相邻的四个点都不能走过,否则可以从之前的某个点直接到那个点。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 11;
 5 int n, m;
 6 int ex, ey, k;
 7 int G[maxn][maxn];
 8 
 9 int dfs(int x,int y,int cnt) {
10     if(x==ex&&y==ey) {
11         if(cnt>=k) {
12             G[x][y] = 1;
13             return 1;
14         }
15         G[x][y] = 0;
16         return 0;
17     }
18     if(x==0||y==0||x>n||y>m) return 0;
19     G[x][y]=-1;
20     if(G[x+1][y]!=-1&&G[x+2][y]!=-1&&G[x+1][y+1]!=-1&&G[x+1][y-1]!=-1&&dfs(x+1,y,cnt+1)) {
21         G[x][y] = 1;
22         return 1;
23     }
24 
25     if(G[x-1][y]!=-1&&G[x-1][y+1]!=-1&&G[x-1][y-1]!=-1&&G[x-2][y]!=-1&&dfs(x-1,y,cnt+1)) {
26         G[x][y] = 1;
27         return 1;
28     }
29 
30     if(G[x][y+1]!=-1&&G[x+1][y+1]!=-1&&G[x-1][y+1]!=-1&&G[x][y+2]!=-1&&dfs(x,y+1,cnt+1)) {
31         G[x][y] = 1;
32         return 1;
33     }
34 
35     if(G[x][y-1]!=-1&&G[x+1][y-1]!=-1&&G[x-1][y-1]!=-1&&G[x][y-2]!=-1&&dfs(x,y-1,cnt+1)) {
36         G[x][y] = 1;
37         return 1;
38     }
39     G[x][y] = 0;
40     return 0;
41 }
42 int main() {
43     // freopen("in", "r", stdin);
44     while(~scanf("%d%d%d%d%d",&n,&m,&ex,&ey,&k)) {
45         memset(G,0,sizeof(G));
46         dfs(1,1,0);
47         for(int i = 1; i <= n; i++) {
48             for(int j = 1; j <= m; j++) {
49                 if(G[i][j]) printf(".");
50                 else printf("*");
51             }
52             printf("\n");
53         }
54     }
55     return 0;
56 }

 

B.trie+dp,子串都丢到trie上,dp(i)代表字符串在[i,len)的最优秀,枚举字符串的后缀,更新dp,dp(0)为最优解。

记录路径:path(i)代表从左到右遍历到第i个字符的时候,这个字符到path(i)的字符为一个子串。输出的时候,输出i到path(i)的字符,之后输出一个空格就可以了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef struct Node {
 5     int id;
 6     bool sign;
 7     Node* next[27];
 8     Node() { for(int i = 0; i < 26; i++) next[i] = NULL; sign = 0; id = -1; }
 9 }Node;
10 const int maxn = 1200500;
11 int n, q;
12 double val[maxn], dp[maxn];
13 char tmp[5555];
14 int path[maxn];
15 
16 void insert(Node* rt, char* str, int id) {
17     Node* cur = rt;
18     for(int i = 0; str[i]; i++) {
19         int id = tolower(str[i]) - 'a';
20         if(cur->next[id] == NULL) cur->next[id] = new Node();
21         cur = cur->next[id];
22     }
23     cur->sign = 1; cur->id = id;
24 }
25 
26 int main() {
27     // freopen("in", "r", stdin);
28     double x;
29     while(~scanf("%d", &n)) {
30         memset(val, 0, sizeof(val));
31         Node* rt = new Node();
32         for(int i = 1; i <= n; i++) {
33             scanf("%s %lf", tmp, &x);
34             insert(rt, tmp, i);
35             int len = strlen(tmp);
36             val[i] = (double)len * len * log(x);
37         }
38         scanf("%d", &q);
39         while(q--) {
40             scanf("%s", tmp);
41             int len = strlen(tmp);
42             memset(dp, 0, sizeof(dp));
43             for(int i = len - 1; i >= 0; i--) {
44                 Node* cur = rt;
45                 for(int j = 0; i + j < len; j++) {
46                     int id = tolower(tmp[i+j]) - 'a';
47                     if(cur->next[id] == NULL) break;
48                     cur = cur->next[id];
49                     if(cur->sign) {
50                         if(val[cur->id] + dp[i+j+1] >= dp[i]) {
51                             dp[i] = val[cur->id] + dp[i+j+1]; path[i] = i + j + 1;
52                         }
53                     }
54                     else {
55                         if(dp[i+j+1] >= dp[i]) {
56                             dp[i] = dp[i+j+1]; path[i] = i + j + 1;
57                         }
58                     }
59                 }
60             }
61             printf("%.10f\n", dp[0]);
62             int p = 0;
63             while(p != len) {
64                 int nx = path[p];
65                 for(int i = p; i < nx; i++) printf("%c", tmp[i]);
66                 printf(" ");
67                 p = nx;
68             }
69             printf("\n");
70         }
71     }
72     return 0;
73 }

 

 

I.感觉就是一道很水的题,注意抠细节。

 

posted @ 2017-05-13 15:24  Kirai  阅读(330)  评论(0编辑  收藏  举报