IT民工
加油!

今天做的是辽宁2010年的省赛题。题目难度比昨天容易了不少。悲哀的是,我们队只把前四道水题做出来了,

后面还有两道相对容易的题没做出来。

A : Dinner

A题是我敲的,开始看到题的时候还愣了一下,后面看到hint的提示,才发现如此之水。题意大致是给你N个盒子,

盒子里面放着一样东西,如果是餐具就输出,注意下格式就可以,餐具在hint中给出了,才四种...

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

const char table[][15] = {"bowl", "knife", "fork", "chopsticks"};

int main()
{
    int n, cnt;
    char str[15];
    while(scanf("%d", &n) != EOF)
    {
        cnt = 0;
        while(n --)
        {
            scanf("%s", str);
            for(int i = 0; i < 4; i ++)
            {
                if(strcmp(str, table[i]) == 0)
                {
                    if(cnt ++)
                        printf(" ");
                    printf("%s", str);
                    break;
                }
            }
        }
        printf("\n");
    }
    return 0;
}

B : You are my brother

这道题是隽遒学弟敲的,他跟我说大致题意是给出N对关系,判断给定的两者的长幼关系,大致就是求到公共祖先的距离,然后按照题意输出一句话来表示两者的关系。

C:Time

这道题是陈兴做的,一道很纯的模拟题。将四个数字按照题意输出,先弄个表,然后打印就行了。

#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
string dig[10][4];
void Prepare()
{
    dig[0][0] = " _ ";
    dig[0][1] = "| |";
    dig[0][2] = "|_|";

    dig[1][0] = "   ";
    dig[1][1] = "  |";
    dig[1][2] = "  |";

    dig[2][0] = " _ ";
    dig[2][1] = " _|";
    dig[2][2] = "|_ ";

    dig[3][0] = " _ ";
    dig[3][1] = " _|";
    dig[3][2] = " _|";

    dig[4][0] = "   ";
    dig[4][1] = "|_|";
    dig[4][2] = "  |";

    dig[5][0] = " _ ";
    dig[5][1] = "|_ ";
    dig[5][2] = " _|";

    dig[6][0] = " _ ";
    dig[6][1] = "|_ ";
    dig[6][2] = "|_|";

    dig[7][0] = " _ ";
    dig[7][1] = "  |";
    dig[7][2] = "  |";

    dig[8][0] = " _ ";
    dig[8][1] = "|_|";
    dig[8][2] = "|_|";

    dig[9][0] = " _ ";
    dig[9][1] = "|_|";
    dig[9][2] = " _|";
}
int main()
{
    int a[4];
    Prepare();
    while(scanf("%d%d%d%d", &a[0], &a[1], &a[2], &a[3]) != EOF)
    {
        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 4; j++)
            {
                cout << dig[a[j]][i];
            }
            putchar('\n');
        }
    }
    return 0;
}

D:SPY

这道题是我和隽遒学弟想出来的思路,然后陈兴敲的,因为我们两个都不会用STL的map,蛋疼,等会学一下,比我想写的hash简单方便多了。

题目给出三个集合,每个集合有一些字符串,要输出同在A和B中,但不在C中的字符串,即A并B - C。先将A的元素插入hash表中,再读入B,

再将C的元素插入hash表中,然后扫一边B,不在C表在A表中的输出。

#include <iostream>
#include <map>
#include <string>
using namespace std;
const int MAXN = 1 << 10;

string strb[MAXN];
int a, b, c;

int main()
{
    while(cin >> a >> b >> c)
    {
        map<string, int> hasha;
        map<string, int> hashc;
        string str;
        for(int i = 0; i < a; i ++)
        {
            cin >> str;
            hasha[str] = 1;
        }

        for(int i = 0; i < b; i ++)
        {
            cin >> strb[i];
        }

        for(int i = 0; i < c; i ++)
        {
            cin >> str;
            hashc[str] = 1;
        }

        int cnt = 0;
        for(int i = 0; i < b; i ++)
        {
            if(hasha[strb[i]] && !hashc[strb[i]])
            {
                if(cnt ++)
                    cout << " ";
                cout << strb[i];
            }
        }
        if(!cnt) cout << "No enemy spy";
        cout << endl;
    }
    return 0;
}

 

E:Intermediary

这道题比赛的时候想了很久还是不会。

F:English Game

AC自动机 + DP,隽遒学弟用Rabin-Karp写没过。

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

const int MAXN = 10010;
const int LEN = 32;
const int X = 10010;
//定义字典树
struct Trie
{
    int end;
    int v;
    struct Trie *son[26];
};

int n, nx;
int buf_cnt;
struct Trie *root, buf[MAXN * LEN];
int max[X];
char x[X];
//新建结点
struct Trie *New_node()
{
    struct Trie *tmp = &buf[buf_cnt ++];
    tmp -> end = 0;
    tmp -> v = 0;
    for(int i = 0; i < 26; i ++)
        tmp -> son[i] = 0;
    return tmp;
}
//插入字符串
void insert(char *s, int v)
{
    struct Trie *cur = root;
    for(int i = 0; s[i] != 0; i ++)
    {
        int id = s[i] - 'a';
        if(cur -> son[id] == NULL)
            cur -> son[id] = New_node();
        cur = cur -> son[id];
    }
    cur -> end = 1;
    cur -> v = v;
}
//翻转字符串
void reversal(char *s)
{
    int i = 0, j = strlen(s);
    j --;
    while(i < j)
    {
        char tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
        i ++, j --;
    }
}

void query(int i)
{
    struct Trie *cur = root;
    for(int j = i; x[j] != 0; j --)
    {
        int id = x[j] - 'a';
        if(cur -> son[id])
        {
            if(cur -> son[id] -> end)
            {
                if(max[j - 1] != -1)
                {
                    if(max[j - 1] + cur -> son[id] -> v > max[i])
                        max[i] = max[j - 1] + cur -> son[id] -> v;
                }
            }
            cur = cur -> son[id];
        }
        else break;
    }
}

int main()
{
    //freopen("test0.in", "r", stdin);
    //freopen("test.out", "wb", stdout);
    x[0] = 0;
    while(scanf("%d %s", &n, x + 1) != EOF)
    {
        nx = strlen(x + 1);
        buf_cnt = 0;
        root = New_node();
        for(int i = 0; i < n; i ++)
        {
            char s[LEN];
            int v;
            scanf("%s %d", s, &v);
            reversal(s);
            insert(s, v);
        }
        max[0] = 0;
        for(int i = 1; i <= nx; i ++)
        {
            max[i] = -1;
            query(i);
        }
        printf("%d\n", max[nx]);
    }
    return 0;
}

 

G:Friends number

最想吐槽的是这道题,我还傻傻的去找规律,最后问了斌牛说打表只需几秒就行。亲和数,真因子之和等于对方的一对数。开始一直在想5000000的

数据范围怎么搞定,后面发现无法搞定。我还是图样图森破...

打表和筛选素数的方法类似:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
const int MAXN = 5000000;
int sum[MAXN + 10];

int main()
{
    freopen("data.txt", "w", stdout);
    int i, j;
    for (i = 0; i <= MAXN ; i ++)
        sum[i] = 1;  //1是所有数的真因数所以全部置1

    for (i = 2; i + i <= MAXN; i ++)
    {
        j = i + i;  //因为真因数,所以不能算本身,所以从它的2倍开始
        while (j <= MAXN)
        {
            //将所有i的倍数的位置上加i
            sum[j] += i;
            j += i;
        }
    }

    for (i = 220; i <= MAXN; i++)   //扫描,O(N)。
    {
        // 一次遍历,因为知道最小是220和284因此从220开始
        if (sum[i] > i && sum[i] <= MAXN && sum[sum[i]] == i)
        {
            //去重,不越界,满足亲和
            cout << i << ", " << sum[i] << "," << endl;
        }
    }
    return 0;
}

打出表之后,直接判断这些数在不在给定的[a,b]内就行了,500万内的亲和数对也不多,才71对。

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

const int pt[][2] =
{
    220, 284,
    1184, 1210,
    2620, 2924,
    5020, 5564,
    6232, 6368,
    10744, 10856,
    12285, 14595,
    17296, 18416,
    63020, 76084,
    66928, 66992,
    67095, 71145,
    69615, 87633,
    79750, 88730,
    100485, 124155,
    122265, 139815,
    122368, 123152,
    141664, 153176,
    142310, 168730,
    171856, 176336,
    176272, 180848,
    185368, 203432,
    196724, 202444,
    280540, 365084,
    308620, 389924,
    319550, 430402,
    356408, 399592,
    437456, 455344,
    469028, 486178,
    503056, 514736,
    522405, 525915,
    600392, 669688,
    609928, 686072,
    624184, 691256,
    635624, 712216,
    643336, 652664,
    667964, 783556,
    726104, 796696,
    802725, 863835,
    879712, 901424,
    898216, 980984,
    947835, 1125765,
    998104, 1043096,
    1077890, 1099390,
    1154450, 1189150,
    1156870, 1292570,
    1175265, 1438983,
    1185376, 1286744,
    1280565, 1340235,
    1328470, 1483850,
    1358595, 1486845,
    1392368, 1464592,
    1466150, 1747930,
    1468324, 1749212,
    1511930, 1598470,
    1669910, 2062570,
    1798875, 1870245,
    2082464, 2090656,
    2236570, 2429030,
    2652728, 2941672,
    2723792, 2874064,
    2728726, 3077354,
    2739704, 2928136,
    2802416, 2947216,
    2803580, 3716164,
    3276856, 3721544,
    3606850, 3892670,
    3786904, 4300136,
    3805264, 4006736,
    4238984, 4314616,
    4246130, 4488910,
    4259750, 4445050,
};

int main()
{
    int a, b;
    while(scanf("%d%d", &a, &b) != EOF)
    {
        int cnt = 0;
        for(int i = 0; i < 71; i ++)
        {
            if(pt[i][0] >= a && pt[i][0] <= b && pt[i][1] >= a && pt[i][1] <= b)
            {
                cnt ++;
            }
        }
        printf("%d\n", cnt);
    }
    return 0;
}

 

H:Happiness Hotel

推出公式是 x^2 - dy^2 = 1,传说中的佩尔方程,不会求他的最小解...

I:NEW RDSP MODE I

 

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

typedef long long LL;

LL PowMod(LL a, LL n, LL mod)
{
    LL ret = 1;
    while(n)
    {
        if(n & 1) ret = ret * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return ret;
}

LL n, m, k;
int main()
{
    while(scanf("%lld%lld%lld", &n, &m, &k) != EOF)
    {
        if(n % 2 == 0) n ++;
        LL t = PowMod(2, m, n);
        if(t == 0) t = n;
        for(int i = 1; i <= k; i ++)
        {
            if(i != 1)
                printf(" ");
            LL ans = t * i % n;
            if(ans == 0) ans = n;
            printf("%lld", ans);
        }
        printf("\n");
    }
    return 0;
}
posted on 2012-10-02 15:46  找回失去的  阅读(176)  评论(0)    收藏  举报