大学生程序设计邀请赛(华东师范大学)
2017-05-13 10:29
246 查看
大学生程序设计邀请赛(华东师范大学)
比赛的时候写了3题,G还没A出来
AEFG/ 6.1补上B和C
A: 拼音魔法
就是模拟,输出拼音标音调后的。
注意a上标音调的话那个字符是占两位char的。
写的真的丑,但是语文太烂了好多不确定。。
代码:
E 黑心啤酒厂
思路:如果n%i==0,直接一杯,不然结果就是i/gcd(n,i)
代码:
F 丽娃河的狼人传说
思路:就是贪心,用r排序
代码:
G 铁路修复计划
思路: 二分+kruskal,二分k的值,求最大可以到多少,用kruskal来判断是否满足条件。
跑了14s…总共也就给了15s,哎
代码:
B 分词
思路:
其实就是考dp,当时没怎么看这道题。。
用dp[i]来表示以i为结尾的最大值,dp[i] = dp[k]+val[thisword];
不过这题改了挺长时间的,注意细节啊。 边界值老是出错。还有刚开始题意都没读懂就开始写了是个什么鬼
代码:
C 袋鼠妈妈
思路: 看了题解才写出来,而且由于写的时候dfs姿势不好还tle,这个故事告诉我们有些大佬的暴力其实跟我们的暴力根本就不一样(没什么联系)。
对这题,只要卡,到这个位置 只能有一条路过来,基本就是正确的结果,把其余位置全部造墙,只有这条路能走,感觉就是瞎搜。。。但是莫名其妙啊,我把way[][]的顺序换了一波才成功ac,不知道哪里出了问题。。
代码:
比赛的时候写了3题,G还没A出来
AEFG/ 6.1补上B和C
A: 拼音魔法
就是模拟,输出拼音标音调后的。
注意a上标音调的话那个字符是占两位char的。
写的真的丑,但是语文太烂了好多不确定。。
代码:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define met(a,b) memset(a,b,sizeof(a)) char s[100][100][5] = { {"a","e","i","o","u","ü"}, {"ā","ē","ī","ō","ū","ǖ"}, {"á","é","í","ó","ú","ǘ"}, {"ǎ","ě","ǐ","ǒ","ǔ","ǚ"}, {"à","è","ì","ò","ù","ǜ"} }; int duiy[26] = {0}; char d[100]; int Find(char x,int dlen) { for(int i = 0; i < dlen; i++) { if(d[i] == x) { if(x=='a' || x=='o' || x=='e' || x == 'v') return i; else if(x =='i') { if(d[i+1] == 'u') return i+1; else return i; } else if(x == 'u') { if(d[i+1] == 'i') return i+1; else return i; } } } return -1; } int print(int xid,int id) { int dlen = strlen(d); for(int i = 0; i < dlen-1; i++) { if(i==xid) printf("%s",s[id][duiy[d[i]-'a']]); else if(d[i] == 'v') printf("ü"); else printf("%c",d[i]); } printf("\n"); } int main() { int t; scanf("%d",&t); char ans[100]; duiy['e'-'a'] = 1; duiy['i'-'a'] = 2; duiy['o'-'a'] = 3; duiy['u'-'a'] = 4; duiy['v'-'a'] = 5; for(int kase = 1; kase <= t; kase ++) { scanf("%s",d); int dlen = strlen(d); int flag = 0; int id; if(d[dlen -1] <='4' && d[dlen-1] >= '1') id = d[dlen-1]-'0'; else id = 0; int aid = -1; for(int i = 0; i < dlen ;i++) { if(d[i] == 'v' && d[i+1] =='e') d[i] = 'u'; } printf("Case %d: ",kase); if(id == 0) { for(int i = 0; i < dlen; i++) { if(d[i] == 'v') printf("ü"); else printf("%c",d[i]); } printf("\n"); continue; } else { int aid = Find('a',dlen); if(aid != -1) print(aid,id); else { int oid = Find('o',dlen); if(oid != -1) print(oid,id); else { int eid = Find('e',dlen); if(eid != -1) print(eid,id); else { int iid = Find('i',dlen); if(iid != -1) print(iid,id); else { int uid = Find('u',dlen); if(uid != -1) { print(uid,id); } else { int vid = Find('v',dlen); if(vid != -1) print(vid,id); } } } 10f8a } } } } return 0; }
E 黑心啤酒厂
思路:如果n%i==0,直接一杯,不然结果就是i/gcd(n,i)
代码:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define met(a,b) memset(a,b,sizeof(a)) int gcd(int a,int b) { if(b==0) return a; else return gcd(b,a%b); } int main() { int n,m; scanf("%d%d",&n,&m); for(int i = 2; i<=m ;i++) { if(n%i==0) { printf("1\n"); } else { int k = gcd(n,i); int x = i/k; printf("%d\n",x); } } return 0; }
F 丽娃河的狼人传说
思路:就是贪心,用r排序
代码:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1005; struct node { int l,r,m; }d[maxn]; bool cmp(node a,node b) { if(a.r == b.r) return a.l < b.l; else return a.r < b.r; } int vis[maxn]; int main() { int t; scanf("%d",&t); for(int kase = 1; kase <= t; kase ++) { memset(vis,0,sizeof(vis)); int n,m,k; scanf("%d%d%d",&n,&m,&k); for(int i = 0; i < k ; i++) { int id; scanf("%d",&id); vis[id] = 1; } int flag = 0; for(int i = 0; i < m ; i++) { scanf("%d%d%d",&d[i].l,&d[i].r,&d[i].m); if(d[i].m > (d[i].r-d[i].l +1)) flag = 1; } printf("Case %d: ",kase); if(flag) { printf("-1\n"); continue; } sort(d,d+m,cmp);int ans = 0; for(int i = 0; i < m; i++) { int num = 0; for(int l = d[i].l; l <= d[i].r; l++) { if(vis[l] == 1) num++; } if(num >= d[i].m) continue; else { int need = d[i].m-num; int x = 0; for(int r = d[i].r; r >= d[i].l; r--) { if(vis[r] == 1) continue; vis[r] = 1; x++; if(x == need) break; } ans += x; } } printf("%d\n",ans); } return 0; }
G 铁路修复计划
思路: 二分+kruskal,二分k的值,求最大可以到多少,用kruskal来判断是否满足条件。
跑了14s…总共也就给了15s,哎
代码:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define LL long long #define met(a,b) memset(a,b,sizeof(a)) const int maxn = 100005; const double eps = 1e-7; int n,m; LL k; struct node { int from,to; double w;int v; node(int x,int a,double b,int c) { from = x;to = a,w = b,v = c; } node(){} }edge[maxn<<1]; node change[maxn<<1]; int f[maxn]; int edgenum = 0; bool cmp(node a,node b) { return a.w<b.w; } int getfather(int i) { if(f[i] == i) return i; else return f[i] = getfather(f[i]); } int kruscal() { sort(change,change+edgenum,cmp); int num = 0; double ans = 0; for(int i = 0; i <= n; i++) f[i] = i; for(int i = 0; i < m; i++) { int a = getfather(change[i].from),b = getfather(change[i].to); if(a!=b) { f[a] = b; double temp = change[i].w; ans += temp; num++; if(num == n-1) break; } } if(ans <= k) return 1; else return 0; } int solve() { double ans = 0; double l = 1,r = 1e8; while(abs(l-r) > eps) { double mid = (l+r)/2.0; memcpy(change,edge,edgenum*sizeof(node)); for(int i = 0;i < edgenum; i++) { if(change[i].v == 1) change[i].w = edge[i].w*mid; } int flag = kruscal(); if(flag) l = mid; else r = mid; } printf("%.6f\n",l); } int main() { for(int i = 0; i < maxn; i++) { f[i] = i; } scanf("%d%d%lld",&n,&m,&k); for(int i = 0; i < m; i++) { int a,b,d; double c; scanf("%d%d%lf%d",&a,&b,&c,&d); edge[edgenum++] = node(a,b,c,d); } solve(); return 0; }
B 分词
思路:
其实就是考dp,当时没怎么看这道题。。
用dp[i]来表示以i为结尾的最大值,dp[i] = dp[k]+val[thisword];
不过这题改了挺长时间的,注意细节啊。 边界值老是出错。还有刚开始题意都没读懂就开始写了是个什么鬼
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <map> #include <cmath> using namespace std; map<string,double> value; const int inf = 0x3f3f3f3f; char data1[5010],data[5010],s[5010]; double dp[5010]; char test[50]; int pre[5010],vis[5010]; const double eps = 1e-9; int tolow(int slen) { for(int i = 0; i < slen; i++) if(isupper(s[i])) s[i] = s[i]+32; return 0; } void tolow2(int dlen) { for(int i = 0; i < dlen; i++){ if(isupper(data1[i])) data[i] = data1[i]+32; else data[i] = data1[i]; } data[dlen] = '\0'; } int main() { int n,m; scanf("%d",&n); double v; for(int i = 0; i < n ; i++) { scanf("%s%lf",s,&v); if(strlen(s) > 30) value[s] = 0; else { int slen = strlen(s); tolow(slen); value[s] = slen*slen*log(v); } } scanf("%d",&m); for(int i = 0; i < m ; i++) { scanf("%s",data1); int dlen = strlen(data1),ansi = -1; tolow2(dlen); double ans = 0; for(int j = 0; j < dlen; j++) dp[j] = 0, pre[j] = -1,vis[j] = 0; for(int j = 0; j < dlen; j++) { double res = 0,th; int k,num; k = j-30 > -1 ? j-30 : -1; for(; k < j; k++) { num = 0,th = 0; for(int x = k+1; x <= j; x++) test[num++] = data[x]; test[num] = '\0'; if(value.count(test)) th = value[test]; if(res < dp[k] + th) { pre[j] = k; res = dp[k]+th; } } dp[j] = res; if(ans < res) ans = res,ansi = j; } printf("%.6f\n",ans); // for(int j = 0; j < dlen; j++)cout<<dp[j]<<endl; int k = ansi; while(k != -1) { vis[k] = 1; k = pre[k]; } for(int j = 0; j < dlen; j++) vis[j]&&j != dlen-1?printf("%c ",data1[j]) : printf("%c",data1[j]); printf("\n"); } return 0; }
C 袋鼠妈妈
思路: 看了题解才写出来,而且由于写的时候dfs姿势不好还tle,这个故事告诉我们有些大佬的暴力其实跟我们的暴力根本就不一样(没什么联系)。
对这题,只要卡,到这个位置 只能有一条路过来,基本就是正确的结果,把其余位置全部造墙,只有这条路能走,感觉就是瞎搜。。。但是莫名其妙啊,我把way[][]的顺序换了一波才成功ac,不知道哪里出了问题。。
代码:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int n,m,x,y,k; int vis[10][10]; int way[4][2] = {0,1,0,-1,-1,0,1,0}; int dfs(int nx,int ny,int s) { if(s >= k && nx == x && ny == y) { for(int i = 0; i < n; i ++) { for(int j = 0; j < m ; j++) vis[i][j] == 1?printf(".") : printf("*"); printf("\n"); } return true; } for(int i = 0; i < 4 ; i++) { int cx = nx + way[i][0], cy = ny + way[i][1]; if(cx < 0 || cx >= n || cy < 0 || cy >= m || vis[cx][cy]) continue; int sum = 0; for(int j = 0; j < 4; j++) if(vis[cx+way[j][0] ][cy + way[j][1]]) sum++; if(sum >= 2) continue; vis[cx][cy] = 1; if(dfs(cx,cy,s+1)) return true;//找到了就不需要找了,不然多找也要费时间。 vis[cx][cy] = 0; } return false; } int main() { scanf("%d%d%d%d%d",&n,&m,&x,&y,&k); vis[0][0] = 1; x--,y--; dfs(0,0,0); return 0; }
相关文章推荐
- EOJ-大学生程序设计邀请赛(华东师范大学)-E-黑心啤酒厂
- 大学生程序设计邀请赛(华东师范大学)-D题(线段树+随机化)
- 大学生程序设计邀请赛(华东师范大学)题解
- A. 拼音魔法 大学生程序设计邀请赛(华东师范大学)
- 大学生程序设计邀请赛(华东师范大学)B. 分词 DP
- EOJ-大学生程序设计邀请赛(华东师范大学)-F-丽娃河的狼人传说
- 大学生程序设计邀请赛(华东师范大学网赛)
- EOJ 3247 大学生程序设计邀请赛(华东师范大学)-G 铁路修复计划
- 2017大学生程序设计邀请赛(华东师范大学)G. 铁路修复计划
- EOJ - 大学生程序设计邀请赛(华东师范大学) F. 丽娃河的狼人传说(贪心)
- EOJ-大学生程序设计邀请赛(华东师范大学)-H-法国传统舞蹈
- EOJ-大学生程序设计邀请赛(华东师范大学)-B-分词
- EOJ-大学生程序设计邀请赛(华东师范大学)-E-黑心啤酒厂
- EOJ-大学生程序设计邀请赛(华东师范大学)-G-铁路修复计划
- 大学生程序设计邀请赛(华东师范大学)
- EOJ-大学生程序设计邀请赛(华东师范大学)-F-丽娃河的狼人传说
- EOJ-大学生程序设计邀请赛(华东师范大学)-C-袋鼠妈妈找孩子
- EOJ-大学生程序设计邀请赛(华东师范大学)-A-拼音魔法
- 大学生程序设计邀请赛(华东师范大学)
- 大学生程序设计邀请赛(华东师范大学)-D-线段树