您的位置:首页 > 其它

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

2017-05-13 10:29 246 查看
大学生程序设计邀请赛(华东师范大学)

比赛的时候写了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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐