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

B 分词

首先建字典树,然后简单dp一下可过,输出有坑!!,因为int没有改成double wa出血。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 26;
const int maxn = 5050;

struct Trie{
    double val;
    Trie *next[MAX];
};

char s[50], query[maxn];
int fa[maxn];
double dp[maxn];
Trie *root;

void Insert(char *s, double val){
    int n = strlen(s);
    Trie *pre = root, *cur;
    for(int i = 0; i < n; i++){
        int id;
        if(s[i] >= 'a' && s[i] <= 'z') id = s[i] - 'a';
        else id = s[i] - 'A';
        if(pre->next[id] == NULL){
            cur = new Trie();
            cur->val = 0;
            for(int j = 0; j < MAX; j++) cur->next[j] = NULL;
            pre->next[id] = cur;
        }
        pre = pre->next[id];
    }
    pre->val = val;
}

double Find(char *s){
    int n = strlen(s);
    Trie *pre = root;
    for(int i = 0; i < n; i++){
        int id;
        if(s[i] >= 'a' && s[i] <= 'z') id = s[i] - 'a';
        else id = s[i] - 'A';
        if(pre->next[id] == NULL) return 0;
        pre = pre->next[id];
    }
    return pre->val;
}

void Delete(Trie *rt){
    if(NULL == rt) return;
    for(int i = 0; i < MAX; i++)
        if(rt->next[i] != NULL) Delete(rt->next[i]);
    delete rt;
    rt = NULL;
}

double cal(double x){
    if(x == 0.0) return 0.0;
    else return log(x);
}

void print(int son){
    if(son == 0) return ;
    print(fa[son]);
    for(int i = fa[son]+1; i <= son; i++)
        printf("%c", query[i]);
    printf(" ");
}

int main(){
    int n, m;
    while(scanf("%d", &n) != EOF){
        root = new Trie();
        for(int i = 0; i < MAX; i++) root->next[i] = NULL;
        double val;
        for(int i = 0; i < n; i++){
            scanf("%s %lf", s, &val);
            Insert(s, val);
        }
        scanf("%d", &m);
        while(m--){
            scanf("%s", query+1);
            memset(dp, 0, sizeof(dp));
            int len = strlen(query+1);
            for(int i = 1; i <= len; i++){
                int tot = 0;
                for(int j = i; j <= i+30 && j <= len; j++){
                    s[tot++] = query[j];
                    s[tot] = '\0';
                    double result = Find(s);
                    if(dp[j] < dp[i-1] + (double)tot*tot*cal(result)){
                        fa[j] = i-1;
                        dp[j] = dp[i-1] + (double)tot*tot*cal(result);
                    }
                }
            }
            double MAX = 0;
            int flag = 0;
            for(int i = 1; i <= len; i++)
                if(dp[i] >= MAX){ MAX = dp[i]; flag = i;}
            printf("%.6lf\n", MAX);
            if(flag == len){
                print(fa[flag]);
                for(int i = fa[flag]+1; i <= len; i++) printf("%c", query[i]);
                printf("\n");
                continue;
            }
            print(flag);
            for(int i = flag+1; i <= len; i++) printf("%c", query[i]);
            printf("\n");
        }
        Delete(root);
    }
    return 0;
}

C 袋鼠妈妈找孩子

非常巧妙地一个深搜,每一个要走的格子,周围最多只能有一格(其实就是走过来的那一格)是走过的。数据量比较小,然后爆搜。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 10;
int dir[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};

char maze[maxn][maxn];
int n, m;
int x, y, k;

int judge(int xx, int yy){
    if(xx < 1 || xx > n || yy < 1 || yy > m) return false;
    return true;
}

bool dfs(int xx, int yy, int t){
    int tot = 0;
    for(int i = 0; i < 4; i++){
        int nx = xx + dir[i][0];
        int ny = yy + dir[i][1];
        if(judge(nx, ny) && maze[nx][ny] == '.') tot++;
    }
    if(tot >= 2) return false;
    if(xx == x && yy == y){
        if(t >= k) return true;
        return false;
    }

    for(int i = 0; i < 4; i++){
        int nx = xx + dir[i][0];
        int ny = yy + dir[i][1];
        if(judge(nx, ny) && maze[nx][ny] == '*'){
            maze[nx][ny] = '.';
            if(dfs(nx, ny, t+1)) return true;
            maze[nx][ny] = '*';
        }
    }
    return false;
}

void init(){
    for(int i = 0; i < maxn; i++)
        for(int j = 0; j < maxn; j++)
            maze[i][j] = '*';
}

int main(){
    while(scanf("%d%d", &n, &m) != EOF){
        init();
        scanf("%d%d%d", &x, &y, &k);
        maze[1][1] = '.';
        dfs(1, 1, 0);
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++)
                printf("%c", maze[i][j]);
            printf("\n");
        }
    }
    return 0;
}

E 黑心啤酒厂

i÷gcd(x,i)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

int gcd(int a, int b){
    return !b?a:gcd(b, a%b);
}

int main(){
    int x, n;
    while(scanf("%d%d", &x, &n) != EOF){
        for(int i = 2; i <= n; i++)
            printf("%d\n", i/gcd(i, x));
    }
    return 0;
}

F 丽娃河的狼人传说

按右端点排序,然后贪心的思想,能往右边放就往右边放。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1100;

struct Node{
    int l, r, t;
    bool operator < (const Node& temp)const{
        return r < temp.r;
    }
}node[maxn];
int val[maxn];

int main(){
    int T;
    scanf("%d", &T);
    for(int kase = 1; kase <= T; kase++){
        memset(val, 0, sizeof(val));
        int n, m, k, x;
        scanf("%d%d%d", &n, &m, &k);
        for(int i = 0; i < k; i++){
            scanf("%d", &x);
            val[x] = 1;
        }
        for(int i = 0; i < m; i++)
            scanf("%d%d%d", &node[i].l, &node[i].r, &node[i].t);
        sort(node, node+m);
        int ans = 0, judge = 0;
        for(int i = 0; i < m; i++){
            int tot = 0;
            for(int j = node[i].l ; j <= node[i].r; j++)
                if(val[j]) tot++;
            if(node[i].r - node[i].l + 1 < node[i].t) {
                judge = 1;
                break;
            }
            if(tot >= node[i].t) continue;
            else ans += node[i].t-tot;
            int temp = node[i].t - tot;
            for(int j = node[i].r ; j >= node[i].l; j--)
                if(!val[j]){
                    val[j] = 1;
                    temp--;
                    if(temp == 0) break;
                }
        }
        printf("Case %d: ", kase);
        if(judge) printf("-1\n");
        else printf("%d\n", ans);
    }
    return 0;
}

G 铁路修复计划

我表示二分的k那么大怎么过的这道题!!二分k然后最小生成树。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const double eps = 1e-7;
const int maxn = 1e5+100;
LL n, m, M;

struct Edge{
    int from, to, t, f;
    double val;
    bool operator < (const Edge& temp)const{
        return val < temp.val;
    }
}e[maxn];

int fa[maxn];

int Find(int x){
    return fa[x] == x?x:fa[x] = Find(fa[x]);
}

bool kruskal(double mid){
    for(int i = 0; i < m; i++)
        if(e[i].f) e[i].val = mid*e[i].t;
        else e[i].val = e[i].t;
    sort(e, e+m);
    for(int i = 0; i < maxn; i++) fa[i] = i;
    double ans = 0;
    for(int i = 0; i < m; i++){
        int xx = Find(e[i].from);
        int yy = Find(e[i].to);
        if(xx != yy){
            fa[xx] = yy;
            ans += e[i].val;
            if(ans > M) return false;
        }
    }
    return true;
}

int main(){
    while(scanf("%lld%lld%lld", &n, &m, &M) != EOF){
        for(int i = 0; i < m; i++)
            scanf("%d%d%d%d", &e[i].from, &e[i].to, &e[i].t, &e[i].f);
        double l = 1.0, r = 1e15;
        while((r-l) > eps){
            double mid = (l+r)/2;
            if(kruskal(mid)) l = mid;
            else  r = mid;
        }
        printf("%.6lf\n", l);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值