搜索
有爱,有技术,有你^_^)y
╱人◕‿‿◕人╲订下契约(注册新用户)

合作站点账号登陆

QQ登录

只需一步,快速开始

快捷导航
查看: 1860|回复: 14
收起左侧

编程之美2013全国挑战赛------资格赛-----题解??

[复制链接]

该用户从未签到

30

主题

127

好友

2万

积分

技术宅认证程序员

重度中二患者

积分
28325
发表于 2013-4-9 01:26:54 | 显示全部楼层 |阅读模式

╱人◕‿‿◕人╲定下契约

您需要 登录 才可以下载或查看,没有账号?╱人◕‿‿◕人╲订下契约(注册新用户)

x
本帖最后由 foodszhu 于 2013-4-9 01:36 编辑

好吧。。。重开一贴有水贴的嫌疑。。。不过作为赛后的发布一下题解还是很有必要的。。。。
但是个人来说。。。虽然小数据都水过了。。。。但无情的大数据只过了第一题orz。。。。。
排名排到400+ 。@Whisper1166 ( W君看了一下跟我一样。。。第一题过了。。第二题WA第三题RE,排名靠的相当近。。。。)
所以在这里也不敢说发什么解题报告。。。毕竟自己还没有做出来。。。但是为了照顾一下刚接触编程的同学。。。。咱们就把问题简单化吧。。。。

这里也非常欢迎大家把自己的AC代码贴出来,尤其是过了大数据的代码。。。如果有空还可以讲解一下最好。。。W君不要吝啬糖哦。。。

题目链接:https://www.gn00.com/t-268811-1-1.html 我也就不再打题目了。。。

---------------------------------------------------------------------------------------------------------------------------------------------
第一题 : 传话游戏

[mw_shl_code=c,true]#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    int T;
    scanf("%d", &T);
    int A = T;
    while(T > 0){
        T--;
        int N,M;
        scanf("%d%d", &N, &M);
        char change[100][2][100] = {{{0}}};
        for(int i = 0; i < M; i++){
            scanf("%s%s", change[0], change[1]);
        }
        char think[100] = {0}, pass[100][100] = {{0}};
        scanf("\n%[^\n]", think);
        int l1 = 0, l2 = 0;
        for(int i = 0; i < strlen(think); i++){
            if(think != ' '){
                pass[l1][l2++] = think;
            } else {
                l1++;
                l2 = 0;
            }
        }
        l1++;
        for(int i = 0; i < N - 1; i++){
            for(int k = 0; k < l1; k++){
                int t = 0;
                for(int j = 0; j < M; j++){
                    if(t == 0 && strcmp(pass[k], change[j][0]) == 0){
                        strcpy(pass[k], change[j][1]);
                        t = 1;
                    }
                }
            }
        }
        printf("Case #%d:", A - T);
        for(int i = 0; i < l1; i++){
            printf(" %s", pass);
        }
        printf("\n");
    }
}[/mw_shl_code]
代码虽然是C风格。。。但是只能交C++,因为大赛编译器不支持c99.。。orz。。。。
三道之中最水一题。。。考究会不会读取字串并分割。。。然后就是替换字串的问题。。。
读取一行含空格的字符串时得用gets或者scanf("\n%[^\n]"),gets前必须加getchar否则不会读入也会导致错误。。。
剩下似乎没什么了。。。注意下一个单词不能在一个人那里来回变(就是要break出来。。。),还有n个游戏者,但是只变n-1次就好了。。。数组稍微开大点。。。就可以过大数据了。。。。

-------------------------------------------------------------------------------------------------------------------------------------------------------
第二题:长方形
[mw_shl_code=applescript,true]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int main(){
    int T;
    scanf("%d", &T);
    for(int t = 0; t < T; t++){
        int N,M,K;
        scanf("%d%d%d", &N, &M, &K);
        if(N > M){
            int tmp = N;
            N = M;
            M = tmp;
        }
        int maxN = 0;
        for(int min = 1, max = 0; min <= N; min++){
            max = K / min;
            if(max > M){
                max = M;
            }
            int remain = K - min * max,  num = min * max * (min - 1) * (max - 1) / 4;
            remain -= remain / min * min;
            if(remain > 1){
                if(max < M){
                    num += max * (remain - 1) * remain / 2;
                } else if(min < N){
                    num += min * (remain - 1) * remain / 2;
                }
            }
            if(num > maxN){
                maxN = num;
            }   
        }
        printf("Case #%d: %d\n", t + 1, maxN);
    }
}[/mw_shl_code]
好吧。。。。这题我是暴力穷举过得。。。。有种淡淡的无奈啊。。。结果看起来穷举都是错的。。。最后大数据WA了。。。不清楚为什么。。。
用了一个简单的公式。。。一个N*M的网格中最多有N*M*(N-1)(M-1) / 4个长方形(证明也很简单,就是乘法原理,横着的边数 * 纵列的边数 = (1 + 2 + 3+.....N) * (1 + 2 + 3......M))
剩下的石子数目肯定少于min(N, M),然后在一个个的铺到较长的那个边上。。。再计算。。。把可能的大矩阵遍历一遍。。。就可以得到最大值了。。。

至于大数据哪里错了还真不知道。。。可能这样子做出来并不一定是最优的也有可能。。。。希望有过大数据的出来讲一下。。。

--------------------------------------------------------------------------------------------------------------------------------------------------------

第三题:树上的三角形
[mw_shl_code=c,true]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int map[200][200] = {{0}}, path[200][200] = {{0}}, dist[200][200] = {{0}}, N = 0;

int floyd(){
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            dist[j] = map[j];
            if(map[j] > 10000){
               path[j] = -1;
           } else {
               path[j] = i;
           }
        }
    }
    for(int k = 0; k < N; k++){
        for(int i = 0; i < N; i++){
            for(int j = 0; j < N; j++){
                if(dist[k] + dist[k][j] < dist[j]){
                    dist[j] = dist[k] + dist[k][j];
                    path[j] = path[k][j];
                }
            }
        }
    }
}
int main(){
    int T;
    scanf("%d", &T);
    for(int t = 0; t < T; t++){
        scanf("%d", &N);
        for(int i = 0; i < 200; i++){
            for(int j = 0; j < 200; j++){
                map[j] = 20000001;
            }
        }
        memset(dist, 0, sizeof(dist));
        memset(path, 0, sizeof(path));
        for(int i = 0; i < N - 1; i++){
            int a, b, len = 0;
            scanf("%d%d%d", &a, &b, &len);
            map[a - 1][b - 1] = len;
            map[b - 1][a - 1] = len;
        }
        floyd();
        printf("Case #%d:\n", t + 1);
        int M = 0;
        scanf("%d", &M);
        for(int i = 0; i < M; i++){
            int S, F, len[1000] = {0}, l = 0;
            scanf("%d%d", &S, &F);
            S--, F--    ;
            if(S == F || path[S][F] == -1){
                printf("No\n");
                continue;
            }
            while(S != F){
                int end = F;
                F = path[S][F];
                len[l++] = map[F][end];
            }
            for(int x = 0; x < l; x++){
                for(int y = x + 1; y < l; y++){
                    if(len[x] > len[y]){
                        int asd = len[x];
                        len[x] = len[y];
                        len[y] = asd;
                    }
                }
            }
            int result = 0;
            for(int k = 1; k < l - 1; k++){
                if(len[k - 1] + len[k] > len[k + 1]){
                    result = 1;
                    break;
                }
            }
            if(result == 0){
                printf("No\n");
            } else {
                printf("Yes\n");
            }
        }
    }
}[/mw_shl_code]

也是某些意义上的暴力过。。。用floyd先求出最短路径,再将最短路径上的树枝长度排序,再判断是否构成三角形。。。。
大数据错的也很明显。。。我数组就开了那么大。。。。肯定RE。。。。

-------------------------------------------------------------------------------------------------------------------------------------
经过这次资格赛发现微软还是很细腻的做了很多工作。。。作为资格赛,题目难度相当于学过C语言课就差不多能过第一题,
一个认真听过算法课的计算机学生就可以答完所有小数据,搞过ACM的应该就可以水过大数据的的样子。。。。
作为一名正在学算法课的学生表示压力山大。。。估计到初赛就一道题都答不上了。。。或许向班里大神要要代码不错。。。。

@Whisper1166 不过初赛可能看样子在版里搞不起来了吧。。。毕竟有时间限制两个小时还是很紧张。。。讨论做不起来的话难道初赛完直接在网上找找题解?。。。。

评分

参与人数 1宅币 +40 贡献 +3 收起 理由
_Nozomi + 40 + 3 o(* ̄▽ ̄*)ブ 发糖

查看全部评分

等死星人
回复

使用道具 举报

该用户从未签到

11

主题

37

好友

1万

积分

第一章

积分
18487
发表于 2013-4-9 08:52:11 | 显示全部楼层
我有同学过了……尼玛。同是大一。差别咋这么大。
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

签到天数: 17 天

连续签到: 1 天

[LV.4]偶尔看看III

298

主题

139

好友

6万

积分

荣誉会员

积分
66622
发表于 2013-4-9 10:29:01 来自手机 | 显示全部楼层
没有考虑大数据…后来想想第二题大数据应该不是特别麻烦
初赛可能也木有时间啊…看那天忙不忙吧,其实发出来题然后大家讨论一下想法和算法设计之类的就好了
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

258

主题

314

好友

3万

积分

第二章

积分
35715
发表于 2013-4-9 11:02:00 | 显示全部楼层
话说接下来有google code jam,有兴趣可以关注一下呢
如果赛制和以前一样的话也是分大数据小数据,不过与编程之美不同的是要自己下它的数据用自己的程序跑完了然后交答案的
博客什么的求人气 http://bimania.org
回复 支持 反对

使用道具 举报

该用户从未签到

30

主题

127

好友

2万

积分

技术宅认证程序员

重度中二患者

积分
28325
 楼主| 发表于 2013-4-9 11:09:39 | 显示全部楼层

看起来不错的样子。。。不过吾辈不是搞算法的人啊。。。看奖项怎么样吧
等死星人
回复 支持 反对

使用道具 举报

签到天数: 1 天

连续签到: 1 天

[LV.1]初来乍到

2

主题

12

好友

4337

积分

序章

积分
4337
发表于 2013-4-9 11:28:32 | 显示全部楼层
擦,报名了忘了做,- -主要是ACM的决赛搞砸了,没心情做- -
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

30

主题

127

好友

2万

积分

技术宅认证程序员

重度中二患者

积分
28325
 楼主| 发表于 2013-4-9 11:31:02 | 显示全部楼层
linyu0077 发表于 2013-4-9 11:28
擦,报名了忘了做,- -主要是ACM的决赛搞砸了,没心情做- -

像乃们这种搞ACM的大神当然无所谓这种小比赛了。。。一直对大神们抱有崇高的敬意。。。加油!
等死星人
回复 支持 反对

使用道具 举报

该用户从未签到

3

主题

25

好友

3668

积分

序章

积分
3668
发表于 2013-4-9 12:24:32 | 显示全部楼层
同求过大数据的~
自己做的只有第一题水过了大数据TAT

第一题:(AC AC)
http://codepad.org/W30EG15t
第二题:(AC WA)
http://codepad.org/LMY8J0DL
第三题:(AC TLE)
http://codepad.org/7lVVY0G2
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

30

主题

127

好友

2万

积分

技术宅认证程序员

重度中二患者

积分
28325
 楼主| 发表于 2013-4-9 12:57:19 | 显示全部楼层
SakuraSa 发表于 2013-4-9 12:24
同求过大数据的~
自己做的只有第一题水过了大数据TAT

C++略高端的样子。。。。唉。。。什么时候也得好好看看STL了。。。虽然说平时用到不多。。。不过对写题很有帮助啊。
等死星人
回复 支持 反对

使用道具 举报

该用户从未签到

6

主题

20

好友

1万

积分

第一章

积分
17868
发表于 2013-4-9 13:38:16 | 显示全部楼层
第一题我用STL水过的,自认为效率应该还算可以,大小数据都AC:
[mw_shl_code=cpp,true]#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int t, n, m;
string org[100], cha[100], msg;
//org=original, cha=changed, msg=message

void getdata()
{
    cin >> n >> m;
       
        for (int i = 0; i < m; i++)
        {
                cin.ignore(1, '\n');
                cin >> org >> cha;
        }
       
        cin.ignore(1, '\n');
        getline(cin, msg);
}

bool change(string &s)
//change a original word into final state
//if the word can't be changed then return false
{
        for (int i = 0; i < m; i++)
        {
                if (s == org)
                {
                        s = cha;
                        return true;
                }
        }
        return false;
}

string transmit()
//get the result that be transmitted
{
        string word, ans;
        stringstream msgs(msg);
        int maxchange = n - 1;
       
        while (msgs >> word)
        {
                int count = 0;
                while (change(word))
                {
                        count++;
                        if (count == maxchange)
                        {
                                break;
                        }
                }
                ans += word + ' ';
        }
       
        ans.erase(ans.length() - 1);

        return ans;
}

int main()
{
        ios::sync_with_stdio(false);
       
        cin >> t;
        for (int i = 1; i <= t; i++)
        {
                getdata();
                string ans = transmit();
                cout << "Case #" << i << ": " << ans << endl;
        }
       
        return 0;
}[/mw_shl_code]
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

6

主题

20

好友

1万

积分

第一章

积分
17868
发表于 2013-4-9 13:40:24 | 显示全部楼层
PM_PM 发表于 2013-4-9 13:38
第一题我用STL水过的,自认为效率应该还算可以,大小数据都AC:
[mw_shl_code=cpp,true]#include
#include ...

弱弱的纠正下,用 std::string 水过的,貌似不算STL
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

30

主题

127

好友

2万

积分

技术宅认证程序员

重度中二患者

积分
28325
 楼主| 发表于 2013-4-9 14:08:37 | 显示全部楼层
PM_PM 发表于 2013-4-9 13:40
弱弱的纠正下,用 std::string 水过的,貌似不算STL

就不要吐槽这些细节了。。。
等死星人
回复 支持 反对

使用道具 举报

签到天数: 1 天

连续签到: 1 天

[LV.1]初来乍到

4

主题

42

好友

1万

积分

喵星人

积分
14935
发表于 2013-4-9 18:26:56 | 显示全部楼层
本帖最后由 libin7099901 于 2013-4-9 18:33 编辑

蛋蛋的飘过....表示...大数据和小数据...喵?????没理解- -...
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

25

主题

59

好友

8779

积分

序章

积分
8779
发表于 2013-4-9 19:41:48 | 显示全部楼层
本帖最后由 terry182 于 2013-4-9 19:43 编辑
轻舟过 发表于 2013-4-9 11:02
话说接下来有google code jam,有兴趣可以关注一下呢
如果赛制和以前一样的话也是分大数据小数据,不过与编 ...

好像看起來不錯哦..  這次Microsoft的就是來不及註冊..混淡我高二就剩幾個月了啊
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

签到天数: 33 天

连续签到: 1 天

[LV.5]常住居民I

138

主题

40

好友

3万

积分

第二章

天堂在哪里?我要去找你..

积分
35560

国庆70周年纪念

发表于 2013-5-11 09:47:04 | 显示全部楼层
辛苦..了
时光与我.终期不遇..
回复 支持 反对

使用道具 举报

本版积分规则

小黑屋|手机版|技术宅(Z站|基宅) ( 粤ICP备18082987号-1 )

GMT+8, 2025-6-16 20:27 , Processed in 0.123026 second(s), 40 queries , Redis On.

Copyright © 2018 技术宅社区

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表