2017年乐山师范学院程序设计大赛解题报告

来源:互联网 发布:java模拟微信浏览器 编辑:程序博客网 时间:2024/06/10 00:50

2017年乐山师范学院程序设计大赛

A 子串

https://www.cnblogs.com/hzoier/p/5908702.html

B 数字组合

题目描述不明确,很多同学误以为只是两个数的组合。

解法一:

直接枚举,每个数选与不选,总的可能是2的20次方,在可以接受的范围内。

#include <cstdio>#include <iostream>#include <cmath>using namespace std;typedef long long ll;const int MAX_N = 30;int arr[MAX_N];ll ans;int n, k;void dfs(int i, int sum) {    if (i == n) {        if (sum == k) {            ++ans;        }        return ;    }    dfs(i + 1, sum);    dfs(i + 1, sum + arr[i]);}int main() {    ans = 0;    scanf("%d%d", &n, &k);    for (int i = 0; i < n; ++i) {        scanf("%d", &arr[i]);    }    dfs(0, 0);    printf("%lld\n", ans);    return 0;}
解法二:

动态规划,维护一个一维数组,dp[s] = k,表示和为s时的方案数为k,针对第i个正整数arr[i],dp[s] += dp[s - arr[i]],从后往前的更新dp数组,避免重复计算。

C 最大间距

对于非ACM的同学来说,很不容易注意到的一点就是C语言4字节整型的表示范围内,最大的正整数和任何负整数之间的差值都超过了4字节整型所能表示的范围。所以要用长整型(long long)来表示结果。

#include <cstdio>#include <iostream>#include <cmath>using namespace std;typedef long long ll;const int MAX_N = 50000 + 10;ll arr[MAX_N];int main() {    int n;    scanf("%d", &n);    for (int i = 0; i < n; ++i) {        scanf("%lld", &arr[i]);    }    ll ans = 0;    for (int i = 0; i < n - 1; ++i) {        ll temp = arr[i + 1] - arr[i];        if (temp < 0) temp = -1 * temp;        if (temp > ans) ans = temp;    }    printf("%lld\n", ans);    return 0;}

D 矩形分割

http://blog.csdn.net/zhhe0101/article/details/52794852
然后我再提供一个自己的思路:由于所有的矩形不会重叠,可以将所有的矩形先投影到X轴上,看成一条线段来解决,用线段树或者树状数组来维护一下,对于每一个矩形,就是更新一下区间[x, x+w],把这段区间的值都加上h,然后再来求解最后的问题。这个思路我没时间写,还在加班,有兴趣的同学可以思考一下。

E 最大子段和

#include <cstdio>#include <iostream>#include <cmath>using namespace std;typedef long long ll;const int MAX_N = 100000 + 10;ll arr[MAX_N];int main() {    int n;    scanf("%d", &n);    for (int i = 0; i < n; ++i) {        scanf("%lld", &arr[i]);    }    int s = 0, t = 0;    ll ans = arr[0];    ll temp = 0;    for (int i = 0; i < n; ++i) {        temp = temp + arr[i];        if (temp > ans) {            ans = temp;        }        if (temp <= 0) {            temp = 0;            s = i + 1;        }    }    printf("%lld\n", ans);    return 0;}

F 最大的数

#include <cstdio>#include <iostream>#include <cmath>using namespace std;typedef long long ll;int main() {    ll m;    scanf("%lld", &m);    m = m * 2;    ll n = sqrt(m);    if (n * (n + 1) > m) n = n - 1;    printf("%lld\n", n);    return 0;}

G 有多少位是7?

#include <cstdio>#include <iostream>#include <cmath>using namespace std;typedef long long ll;int main() {    int m;    scanf("%d", &m);    int cnt = 0;    while (m > 0) {        if (m % 10 == 7) ++cnt;        m /= 10;    }    printf("%d\n", cnt);    return 0;}

H 棋盘分割

http://blog.csdn.net/Clove_unique/article/details/52936610

I 派

只需二分答案即可

#include <cstdio>#include <iostream>#include <cmath>#include <algorithm>#include <string>#include <cstring>#include <vector>#include <map>using namespace std;typedef long long ll;const int MAX_N = 10000 + 10;double arr[MAX_N];int n, f;bool C(double x) {    int num = 0;    for (int i = 0; i < n; ++i) {        num += (int)(arr[i] / x);    }    //cout << "x=" << x << " num=" << num << endl;    return num >= f;}int main() {    double PI = 3.1415926535897932384626433832795;    scanf("%d%d", &n, &f);    f += 1;    for (int i = 0; i < n; ++i) {        scanf("%lf", &arr[i]);        arr[i] = arr[i] * arr[i] * PI;    }    double lb = 0, ub = 1000000000 + 10;    for (int i = 0; i < 100; ++i) {        double mid = (ub + lb) / 2;        if (C(mid)) lb = mid;        else ub = mid;        //cout << lb << " " << ub << endl;    }    //cout << ub << endl;    //ub = floor(ub * 1000) / 1000;    printf("%.3lf\n", ub);    return 0;}

J 求圆的半径

#include <cstdio>#include <iostream>#include <cmath>using namespace std;typedef long long ll;int main() {    double s;    scanf("%lf", &s);    double pi = 3.1415;    s = s / pi;    s = sqrt(s);    printf("%.3lf\n", s);    return 0;}

K 倒排索引

倒排索引(Elastic Search)是搜索引擎中常见并且重要的数据结构。

#include <cstdio>#include <iostream>#include <cmath>#include <algorithm>#include <string>#include <cstring>#include <vector>#include <map>using namespace std;typedef long long ll;const int MAX_N = 100000 + 10;map<string, vector<int> > mp;int main() {    ios::sync_with_stdio(false);    cin.tie(NULL);    cout.tie(NULL);    mp.clear();    int n;    cin >> n;    for (int i = 1; i <= n; ++i) {        int c;        cin >> c;        while (c-- > 0) {            string s;            cin >> s;            mp[s].push_back(i);        }    }    int m;    cin >> m;    for (int i = 0; i < m; ++i) {        string s;        cin >> s;        bool first = true;        int t = -1;        for (int j = 0; j < mp[s].size(); ++j) {            if (mp[s][j] == t) continue;            if (first) {                cout << mp[s][j];                first = false;            }            else cout << " " << mp[s][j];            t = mp[s][j];        }        if (mp[s].size() <= 0) cout << "NOT FOUND";        cout << endl;    }    return 0;}

以上所有代码均来自比赛中的第一名

阅读全文
0 0