IT民工
加油!

今天做的是第五届河南省省赛,我挫到爆了,只出了三题,都是水题,个人赛垫底。

先总结一下,今天写最水的A题居然WA了两次,关键是调了半个小时,浪费了不少时间,也影响了心情。然后做的是同样水的

F题,还好敲的比较快,也顺利一A。然后剩下三个多小时在梦游,将D题敲到了200多行,WA了2次,中途去写了G题,结果题意看错了,

WA了1次,看各位大牛已经A到了7题,又回来写D题,还是WA,最后才想到B题过的人也那么多,所以去写B题,WA了两次才A。惨不忍睹!

A:奇怪的排序

将一个数组的所有数翻转,然后从小到大排序,输出排序后的结果,例如13翻转成31,超级水的一道题,真心不应该

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int MAXD = 60;
typedef struct Node
{
    int x, y;
}E;
E e[MAXD];
int A, B;

int cmp(const void *_p, const void *_q)
{
    E *p = (E *)_p;
    E *q = (E *)_q;
    return p -> y - q -> y;
}

int main()
{
    int n;
    scanf("%d", &n);
    while(n --)
    {
        scanf("%d%d", &A, &B);
        int k = 0;
        for(int i = A; i <= B; i ++)
        {
            e[k].x = i;
            char str[20];
            int t = i, m = 0;
            while(t)
            {
                str[m ++] = t % 10 + '0';
                t /= 10;
            }
            str[m] = '\0';
            //printf("%s\n", str);
            int s = 1, j;
            e[k].y = 0;
            for(j = strlen(str) - 1; j >= 10; )
                if(str[j] == '0') j --;
            for(; j >= 0 ; j --)
            {
                e[k].y += (str[j] - '0') * s;
                s *= 10;
            }
            //printf("%d\n", e[k].y);
            k ++;
        }
        qsort(e, k, sizeof e[0], cmp);
        k --;
        for(int i = 0; i < k; i ++)
        {
            printf("%d ", e[i].x);
        }
        printf("%d\n", e[k].x);

    }
    return 0;
}

B: 最强DE 战斗力

将一个1000以内的数拆成N个数,N不给出,自己判断,使得这N个数的乘积最大,需要用到高精度,但是这不是关键。最后才想到拆成3 和 2是最优的,优先选3。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

const int base = 10000;
const int width = 4;
const int N = 1000;
struct bint
{
    int ln, v[N];
    bint (int r = 0)
    {
        for(ln = 0; r > 0; r /= base) v[ln ++] = r % base;
    }
    bint & operator = (const bint& r)
    {
        memcpy(this, &r, (r.ln + 1) * sizeof (int));
        return *this;
    }
};

/*
bool operator <(const bint& a, const bint& b)
{
    int i;
    if(a.ln != b.ln) return a.ln < b.ln;
    for(i = a.ln - 1; i >= 0 && a.v[i] == b.v[i]; i --)
    {
        return i < 0 ? 0 : a.v[i] < b.v[i];
    }
}
*/

bint operator * (const bint& a, const bint& b)
{
    bint res;
    res.ln = 0;
    if(0 == b.ln) {res.v[0] = 0; return res;}
    int i, j, cy;
    for(i = 0; i < a.ln; i ++)
    {
        for(j = cy = 0; j < b.ln || cy > 0; j ++, cy /= base)
        {
            if(j < b.ln) cy += a.v[i] * b.v[j];
            if(i + j < res.ln) cy += res.v[i + j];
            if(i + j >= res.ln) res.v[res.ln ++] = cy % base;
            else res.v[i + j] = cy % base;
        }
    }
}

bool read(bint& b, char buf[])
{
    //if(1 != scanf("%s", buf)) return 0;
    int w, u, ln = strlen(buf);
    memset(&b, 0, sizeof(bint));
    if('0' == buf[0] && 0 == buf[1]) return 1;
    for(w = 1, u = 0; ln; )
    {
        u += (buf[-- ln] - '0') * w;
        if(w * 10 == base)
        {
            b.v[b.ln ++] = u, u = 0, w = 1;
        }
        else w *= 10;
    }
    if(w != 1) b.v[b.ln ++] = u;
    return 1;
}

void write(const bint& v)
{
    int i;
    printf("%d", v.ln == 0 ? 0 : v.v[v.ln - 1]);
    for(i = v.ln - 2; i >= 0; i --)
        printf("%04d", v.v[i]);
    printf("\n");
}

int n, t;
bint s, v, u;

int main()
{
    scanf("%d", &n);
    while(n --)
    {
        scanf("%d", &t);
        int k = t / 3;
        char str1[10] = "1", str2[10] = "2", str3[10] = "3";
        read(s, str1);
        read(v, str2);
        read(u, str3);
        //write(s);
        //write(v);
        //write(u);
        for(int i = 0; i < k - 1; i ++)
        {
            s = s * u;
        }
        if(t % 3 == 1)
        {
            s = s * v;
            s = s * v;
        }
        else if(t % 3 == 2)
        {
            s = s * u;
            s = s * v;
        }
        else
        {
            s = s * u;
        }
        write(s);
    }
    return 0;
}

C: 试 制 品

一道关于字符串的题,暂时没看。

D:遥控器

这道题是一道类似模拟调频道的题。


Dr.Kong 有一台高级电视机,这台电视机可以接受100个频道(从0到99编号)。电视的配套
遥控器有13个按钮:
1    2   3   ↑
4    5    6   ↓
7    8   9
—   0
当按"↑"键时,当前频道编号会增加1(如果当前为99频道,则会切换到0频道)。如果按"↓"
键,当前频道编号会减小1(如果当前为0频道,则会切换到99频道)。当要切换到0~9频道时,可以
直接在遥控器上按相应的键。当要切换到10~99频道时,可以先按"—"键,然后按2个与频道编号
相对应的数字键(即先按与频道编号的十位数字相对应的键,然后按与个位数字相对应的键)。
由于遥控器长时间的使用和某些未知原因,遥控器上的某些键已经坏了,不能再起作用了。
现在你的任务是,能否告诉Dr.Kong,如何用最少的按键次数来将频道从编号X切换到编号Y。

我当时是根据键来枚举,越来越乱,越写越多,最后就悲剧了。

其实应该按照步数来枚举,枚举需要按上下键的步数。如果我们只通过按上下的话,从X到Y的步数可以直接求。

从任一个可通过按数字键到的频道到Y的步数 + 数字键到该频道的步数也可以求。然后找出最小值即可。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int a[15];
int x, y;
int cnt, ans;
int id(int x)
{
    if(x < 0)
        return x + 100;
    else
        return x % 100;
}

int min(int a, int b)
{
    if(a == -1)
        return b;
    else
        return a < b ? a : b;
}

int to(int x)
{
    x = id(x);
    if(x / 10 == 0)
    {
        return a[x];
    }
    int tx = x / 10, bx = x % 10;
    if(a[10] && a[tx] && a[bx])
        return 3;
    return 0;
}

int main()
{
    //freopen("543.in", "r", stdin);
    //freopen("D.out", "w", stdout);
    int t;
    scanf("%d", &t);
    while(t --)
    {
        ans = -1;
        scanf("%d%d%d%d", &a[1], &a[2], &a[3], &a[11]);
        scanf("%d%d%d%d", &a[4], &a[5], &a[6], &a[12]);
        scanf("%d%d%d", &a[7], &a[8], &a[9]);
        scanf("%d%d", &a[10], &a[0]);
        scanf("%d%d", &x, &y);
        //枚举步数
        for(int i = 0; i < 100; i ++)
        {
            if(a[11])
            {
                if(id(y - i) == x) //向上按i次
                    ans = min(ans, i);
                else if(to(y - i)) //可以到一个频道 + 向上i次
                    ans = min(ans, to(y - i) + i);
            }
            if(a[12])
            {
                if(id(y + i) == x)//向下按i次
                {
                    ans = min(ans, i);
                }
                else if(to(y + i))//到一个频道 + 向下i次
                    ans = min(ans, to(y + i) + i);
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

比赛时写的挫B代码:

View Code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int a[15];
int x, y;
int cnt, ans;

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
        ans = 110;
        scanf("%d%d%d%d", &a[1], &a[2], &a[3], &a[11]);
        scanf("%d%d%d%d", &a[4], &a[5], &a[6], &a[12]);
        scanf("%d%d%d", &a[7], &a[8], &a[9]);
        scanf("%d%d", &a[10], &a[0]);
        scanf("%d%d", &x, &y);
        int cur, ty, by;
        bool ok = false;
        if(a[11])
        {
            ok = true;
            if(y < x)
            {
                cnt = y + 99 - x;
                ans = min(cnt, ans);
            }
            else
            {
                cnt = y - x;
                ans = min(cnt, ans);
            }
        }
        if(a[12])
        {
            ok = true;
            if(y < x)
            {

                cnt = x - y;
                ans = min(cnt, ans);
            }
            else
            {
                cnt = x + 99 - y;
                ans = min(cnt, ans);
            }
        }

        if(y < 10)
        {
            if(a[y])
            {
                cnt = 1;
                if(cnt < ans) ans = cnt;
                ok = true;
            }
            else
            {
                cur = y;
                if(a[11])
                {

                    while(cur --)
                    {
                        if(a[cur])
                        {
                            cnt = y - cur;
                            if(cnt < ans) ans = cur;
                            ok = true;
                            break;
                        }
                        if(cur == -1) cur = 99;
                        if(cur >= 10)
                        {
                            if(!a[10]) break;
                            ty = cur / 10, by = cur % 10;
                            if(a[ty] && a[by])
                            {
                                ok = true;
                                cnt = 3;
                                cnt += (y + 99 - cur);
                                if(cnt < ans) ans = cnt;
                            }
                        }
                    }
                }
                cur = y;
                if(a[12])
                {
                    while(cur ++)
                    {
                        if(a[cur])
                        {
                            cnt = cur - y;
                            if(cnt < ans) ans = cur;
                            ok = true;
                            break;
                        }
                        if(cur == 100) cur = 0;
                        if(cur >= 10)
                        {
                            if(!a[10]) break;
                            ty = cur / 10, by = cur % 10;
                            if(a[ty] && a[by])
                            {
                                ok = true;
                                cnt = 3;
                                cnt += (cur - y);
                                if(cnt < ans) ans = cnt;
                            }
                        }
                    }
                }
            }
        }
        else
        {
            ty = y / 10, by = y % 10;
            if(a[ty] && a[by])
            {
                cnt = 3;
                ans = min(cnt, ans);
                ok = true;
            }
            else
            {
                cur = y;
                if(a[11])
                {
                    while(cur --)
                    {
                        if(cur > 0)
                    }
                }
            }
        }
    }

}

E:奇妙的图案

计算几何,暂时先不搞。

F:Metric    Matrice

判断一个矩阵是不是最短路径的矩阵。是的话输出”0“,否则看违反了下哪条规则就输出几,遍历五遍矩阵就可以了。

 

A distance matrix a[i][j] is a metric if and only if
    1.    a[i][i] = 0
2,    a[i][j]> 0    if i != j
    3.    a[i][j] = a[j][i]
4.    a[i][j] + a[j][k] >= a[i][k]   i != j != k

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int MAXN = 35;
int a[MAXN][MAXN];
int n;

int judge()
{
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            if(a[i][i] != 0)
                return 1;
        }
    }

    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            if(i == j) continue;
            if(a[i][j] <= 0)
                return 2;
        }
    }

    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            if(a[i][j] != a[j][i])
                return 3;
        }
    }

    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            for(int k = 0; k < n; k ++)
            {
                if(i == j || j == k || i == k) continue;
                if(a[i][j] + a[j][k] < a[i][k])
                    return 4;
            }
        }
    }

    return 0;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
        scanf("%d", &n);
        for(int i = 0; i < n; i ++)
            for(int j = 0; j < n; j ++)
                scanf("%d", &a[i][j]);
        printf("%d\n", judge());
    }
    return 0;
}

G: Divideing   Jewels

给出权值从1到10的物品的各自的数目,然后问是否能平均分给两个人,使得两个人拿到的物品的总价值相等。首先判断所有物品的总价值是不是偶数,是偶数

的话再看能不能将这些物品分配到一个人手里,使得他获得的价值是总价值的一半。可以转化成多重背包问题,知道了物品的价值和数目,我们可以将物品的体积

设成和它的价值相同,然后用一个总价值一半体积的背包来装这些物品,看最终获得的最大价值是不是等于它的体积。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int MAXN = 100005;
int a[15], f[MAXN], V;

void ZeroOnePack(int F[], int C, int W)
{
    for(int v = V; v >= C; v --)
        F[v] = max(F[v], F[v - C] + W);
}

void CompletePack(int F[], int C, int W)
{
    for(int v = C; v <= V; v ++)
        F[v] = max(F[v], F[v - C] + W);
}

void MultiplePack(int F[], int C, int W, int M)
{
    if(C * M >= V)
    {
        CompletePack(F, C, W);
        return;
    }
    int k = 1;
    while(k < M)
    {
        ZeroOnePack(F, k * C, k * W);
        M -= k;
        k <<= 1;
    }
    ZeroOnePack(F, C * M, W * M);
}

int main()
{
    int t = 0;
    while(true)
    {
        int total = 0;
        for(int i = 1; i <= 10; i ++)
        {
            scanf("%d", &a[i]);
            total += a[i] * i;
        }
        if(total == 0) break;
        ++ t;
        if(total & 1)
            printf("#%d:Can't be divided.\n", t);
        else
        {
            int target = total >> 1;
            memset(f, 0, sizeof f);
            V = target;
            for(int i = 1; i <= 10; i ++)
            {
                MultiplePack(f, i, i, a[i]);
            }
            if(f[target] == target)
            {
                printf("#%d:Can be divided.\n", t);
            }
            else
                printf("#%d:Can't be divided.\n", t);
            printf("\n");
        }
    }
    return 0;
}

 

H: Interesting Punch-Bowl

神题,貌似当时他们省赛没人过,但是被斌牛搞定了。

 


 

posted on 2012-10-05 17:11  找回失去的  阅读(239)  评论(0编辑  收藏  举报