Android应用基础学习记录

时间:2014-04-27 21:18:00   收藏:0   阅读:466

福州大学第十一届程序设计竞赛
Contest Finished!
Tag Pro.ID Problem Title Ratio(AC/Submit)
mamicode.com,码迷 1 大王叫我来巡山呐 80.31%(261/325)
mamicode.com,码迷 2 防守阵地 I 23.48%(193/822)
mamicode.com,码迷 3 shadow 13.23%(97/733)
mamicode.com,码迷 4 花生的序列 12.07%(21/174)
mamicode.com,码迷 5 防守阵地 II 14.98%(68/454)
  6 巡了南山我巡北山 0.00%(0/45)
mamicode.com,码迷 7 Nostop 20.79%(21/101)
  8 卷福的难题 10.00%(1/10)
        

               本来打算当作组队赛来做的,结果队友有足球赛,还有一个有党校。。只剩下我一个人单挑了。 @.@   还好不是很难,不然就被虐翻了。。整体来说题目比较简单,应该本来就是作为个人赛准备的。。

               A题签到题

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;

const int maxn = 5;
const int INF = 0x3f3f3f3f;

int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        int ans = n / 7 * 2;
        if(n % 7 == 6) ans ++;
        printf("%d\n", ans);
    }
}

                  B题观察式子转移,就可以很容易发现端倪了。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;

const int maxn = 1001000;
const int INF = 0x3f3f3f3f;

int a[maxn];

int main()
{
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        int ans = 0, tot = 0, sum = 0;
        for(int i = 1; i <= m; i ++)
        {
            scanf("%d", &a[i]);
            sum += a[i];
            tot += i*a[i];
        }
        ans = tot;
        for(int i = m + 1; i <= n; i ++)
        {
            scanf("%d", &a[i]);
            tot -= sum;
            sum -= a[i - m];
            sum += a[i];
            tot += a[i] * m;
            ans = max(ans, tot);
        }
        printf("%d\n", ans);
    }
}
             C题是比较简单的树dp吧,只需要看孩子和本身有没有士兵,有的话当前点肯定会被消灭。OJ比较奇特,递归会爆栈,用vector会超时。。不幸的是两种情况我都遇到了。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define MP make_pair
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;

const int maxn = 100100;
const int INF = 0x3f3f3f3f;

int arm[maxn];
bool hav[maxn];

struct Edge
{
    int u, v;
}E[maxn*2];

int fir[maxn], nxt[maxn*2], tot = 0;

LL d[maxn];

void AddEdge(int u, int v)
{
    E[tot].u = u, E[tot].v = v;
    nxt[tot] = fir[u], fir[u] = tot ++;
}

LL dfs()
{
    stack<pair<int, int> > S;
    CLR(d, 0);
    S.push(MP(1, 0));
    int cnt = 0;
    while(!S.empty())
    {
        int u = S.top().first, fa = S.top().second;
        if(fir[u] == -1)
        {
            if(hav[u]) hav[fa] = 1, d[fa] += d[u] + arm[u];
            S.pop();
        }
        else
        {
            int v = E[fir[u]].v;
            fir[u] = nxt[fir[u]];
            if(v == fa) continue;
            S.push(MP(v, u));
        }
    }
    return d[1];
}

int main()
{
    int n, k;
    while(scanf("%d%d", &n, &k) != EOF)
    {
        for(int i = 1; i <= n; i ++)
        {
            scanf("%d", &arm[i]);
        }
        CLR(hav, 0);CLR(fir, -1); tot = 0;
        for(int i = 0; i < k; i ++)
        {
            int u; scanf("%d", &u);
            hav[u] = 1;
        }
        for(int i = 1; i < n; i ++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            AddEdge(u, v);
            AddEdge(v, u);
        }

        printf("%lld\n", dfs());
    }
}
            D题算是一道dp吧,dp[i][j],表示到第i为为止,有j个属于第一个串,因为串的特殊性(WBWBWB),所以很容易判断当前位置的字母满足的情况。比如当前j为奇数,那么j后面肯定只能接B。。。就这样。。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;

const int maxn = 10100;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

char ch[maxn];
int dp[2][3300];

int main()
{
    int T, n;
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d%s", &n, ch);
        CLR(dp, 0);
        dp[0][0] = 1;
        for(int i = 0, j = 1; i < n * 2; i ++, j ++)
        {
            CLR(dp[j&1], 0);
            if(ch[i] == ‘B‘)
            {
                for(int k = 0; k <= n; k ++)
                {
                    if(k&1) dp[j&1][k+1] = (dp[j&1][k+1] + dp[i&1][k]) % MOD;
                    if((i-k)&1) dp[j&1][k] = (dp[j&1][k] + dp[i&1][k]) % MOD;
                }
            }
            else
            {
                for(int k = 0; k <= n; k ++)
                {
                    if((k&1) == 0) dp[j&1][k+1] = (dp[j&1][k+1] + dp[i&1][k]) % MOD;
                    if(((i-k)&1) == 0) dp[j&1][k] = (dp[j&1][k] + dp[i&1][k]) % MOD;
                }
            }
        }
        printf("%d\n", dp[0][n]);
    }
}
               E裸线段树区间更新,区间查询,只要你不想那么多,就可以直接A掉。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
using namespace std;

const int maxn = 100100;
const int INF = 0x3f3f3f3f;

int add[maxn<<2];
int sum[maxn<<2];

void PushUp(int rt)
{
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m)
{
    if (add[rt])
    {
        add[rt<<1] += add[rt];
        add[rt<<1|1] += add[rt];
        sum[rt<<1] += add[rt] * (m - (m >> 1));
        sum[rt<<1|1] += add[rt] * (m >> 1);
        add[rt] = 0;
    }
}
void build(int l,int r,int rt)
{
    add[rt] = 0;
    if (l == r)
    {
        scanf("%d",&sum[rt]);
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if (L <= l && r <= R)
    {
        add[rt] += c;
        sum[rt] += c * (r - l + 1);
        return ;
    }
    PushDown(rt , r - l + 1);
    int m = (l + r) >> 1;
    if (L <= m) update(L , R , c , lson);
    if (m < R) update(L , R , c , rson);
    PushUp(rt);
}
int query(int L,int R,int l,int r,int rt)
{
    if (L <= l && r <= R)
    {
        return sum[rt];
    }
    PushDown(rt , r - l + 1);
    int m = (l + r) >> 1;
    LL ret = 0;
    if (L <= m) ret += query(L , R , lson);
    if (m < R) ret += query(L , R , rson);
    return ret;
}
int main()
{
    int n, m, q;
    while(scanf("%d%d%d", &n, &m, &q) != EOF)
    {
        build(1, n, 1);
        for(int i = 0; i < q; i ++)
        {
            int x; scanf("%d", &x);
            printf("%d\n", query(x, x + m - 1, 1, n, 1));
            update(x, x + m - 1, -1, 1, n, 1);
        }
    }
}


                F应该是搜索吧。。。感觉无从下手,罪过。。。大致思路应该是判断是否是子串,然后在进行加字符,copy操作吧。。。我猜的。。

                G题这种题第一次见到,感觉自己YY出来还是很高兴的!就是用矩阵来表示走K步之后的各个点对到达所需要的最小花费。这样的话,我们就可以用初始矩阵(表示的是1步到达的情况)不断更新,来获得走2步,走3步的到达情况。。这样的话思路就很明确了。因为题目数据比较大,我们直接用快速幂更新就可以了。(应该很容易想到这些更新是满足结合率的吧)。我还是觉得看代码清楚些。。这个OJ很个性,用lld,wa了无数次,改成cin,cout才过。。。=.=!!

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define LL long long
#define MP make_pair
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 55;
const LL INF = 1ll << 60;

struct Matrix
{
    LL m[maxn][maxn];
}sol, pre;

int n;

Matrix Add(Matrix a, Matrix b)
{
    Matrix ret;
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= n; j ++)
        {
            ret.m[i][j] = INF;
            LL& tmp = ret.m[i][j];
            for(int k = 1; k <= n; k ++)
            {
                tmp = min(tmp, a.m[i][k] + b.m[k][j]);
            }
        }
    }
    return ret;
}

Matrix Mul(Matrix a, int n)
{
    Matrix ret;
    bool flag = false;
    while(n)
    {
        if(n & 1)
        {
            if(flag) ret = Add(ret, a);
            else ret = a;
            flag = true;
        }
        a = Add(a, a);
        n >>= 1;
    }
    return ret;
}

void pt(Matrix sol)
{
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= n; j ++)
            printf("%lld ", sol.m[i][j]);
            puts("");
    }
}

int main()
{
    int h, k, T;
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d%d%d", &n, &h, &k);
        for(int i = 1; i <= n; i ++)
        {
            for(int j = 1; j <= n; j ++)
                sol.m[i][j] = INF;
        }
        for(int i = 0; i < h; i ++)
        {
            int u, v;LL c;
            scanf("%d%d", &u, &v); cin >> c;
            sol.m[u][v] = min(sol.m[u][v], c);
        }
        sol = Mul(sol, k);
        if(sol.m[1][n] == INF) puts("-1");
        else cout << sol.m[1][n] << endl;
        //printf("%lld\n", sol.m[1][n]);
    }
}
                 H题完全没想法,最后绝杀的那个人真厉害,ORZ~~


评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!