您的位置:首页 > 其它

ACM-2011 PKU 比赛

2011-05-11 10:12 211 查看
上周末去参加了北京大学的ACM赛,10道题目,做出了两道(感觉没脸说)A题和C题,哈哈……先讲讲这两道题吧。

A题:http://poj.openjudge.cn/campus2011/A/

大意是,早锻炼打卡,每学期要打够早锻炼10次,晚锻炼20次。早上7点到9:30为早锻炼时间,晚上必须打卡两次,相隔半个小时,才算一次晚锻炼。打卡时间已经排好序了。

这道题主要考虑的是,一早上不能重复打卡,第二晚上打卡必须超过半小时,晚上重复打卡的情况比较复杂。但是搞清楚逻辑还是可以过得。

代码如下:

#include<stdio.h>
#define ONLINE
void online()
{
#ifdef ONLINE
#else
freopen("acm1.in", "r", stdin);
freopen("acm1.out", "w", stdout);
#endif
}
const int MORN = 1;
const int HALF = 2;
const int morn = 10;
const int half = 20;
int mnumber = 0;
int hnumber = 0;
struct Time
{
int h;
int m;
int s;
int yy;
int mm;
int dd;
};
Time lastt, newt;
int lasttype = 0;
int istime(Time t)
{
int type =0;
if(t.h == 7)
return MORN;
if(t.h == 8 && t.m >=0 && t.m <= 30)
return MORN;
if(t.h >= 16 && t.h < 21)
return HALF;
if(t.h==21 && t.m>=0 && t.m <= 30)
return HALF;
return 0;
}
int main()
{
online();
//找到第一个合法时间
while(scanf("%d%d%d%d%d%d", &newt.h, &newt.m, &newt.s, &newt.yy,&newt.mm, &newt.dd) != EOF)
{
int type = istime(newt);
if(type == 0)
continue;
if(type == MORN)
{
mnumber ++;
lasttype = MORN;
lastt = newt;
break;
}
if(type == HALF)
{
lastt = newt;
lasttype = HALF;
break;
}
}

while(scanf("%d%d%d%d%d%d", &newt.h, &newt.m, &newt.s, &newt.yy,&newt.mm, &newt.dd) != EOF)
{
int type = istime(newt);
if(type == 0)
continue;
if(type == MORN)
{
if(lasttype == MORN)
{
if(newt.yy == lastt.yy && newt.mm == lastt.mm && newt.dd == lastt.dd)
{
continue;
}
}
mnumber ++;
lastt = newt;
lasttype = type;
}
if(type == HALF)
{
if(lasttype == MORN)
{
lastt = newt;
lasttype = type;
continue;
}
if(lasttype == HALF)
{
if(newt.yy == lastt.yy && newt.mm == lastt.mm && newt.dd == lastt.dd)
{
if((newt.m-lastt.m) * 60 + (newt.h - lastt.h)* 3600 + newt.s - lastt.s >= 1800)
{
hnumber ++;
lasttype = 0;
continue;
}//end if
}
else
{
lastt = newt;
continue;
}
}
if(lasttype == 0)
{
if(newt.yy == lastt.yy && newt.mm == lastt.mm && newt.dd == lastt.dd)
{
lasttype = 0;
continue;
}
else
{
lastt = newt;
lasttype = type;
continue;
}
}
}
}
int mresult = morn - mnumber;
int hresult = half - hnumber;
if(mresult < 0)
mresult = 0;
if(hresult < 0)
hresult = 0;
printf("%d %d", mresult, hresult);
return 0;
}


当时比较紧张吧,有一些特殊情况没有考虑好,另一方面用例也没有设计好,结果导致了出错的。

C题:http://poj.openjudge.cn/campus2011/C/

大意是一个单词变化到另一个单词的最短步骤吧,这道题让我想到了两个字符串相似度的编辑距离算法。我当时的思路是,计算出两两单词之间通过一次变换可以得到的情况,得到一个记录数组,然后采用最短距离的思想,求出原单词到目标单词的距离。

源代码如下:

#include<stdio.h>
#include<string.h>
#define ONLINE
void online()
{
#ifdef ONLINE
#else
freopen("acm3.in", "r", stdin);
freopen("acm3.out", "w", stdout);
#endif
}
const int N = 6002;
const int SIZE = 100;
char start[SIZE];
char end[SIZE];
char lexicon
[SIZE];
int used
= {0};
int len;
bool flag = false;
bool equal = false;
int map

= {0};
int path
;
int load
;
int pl=0;
int lenword(int a, int b)
{
int l1 = strlen(lexicon[a]);
int l2 = strlen(lexicon[b]);
int change =2;
if(l1 == l2)
{
change= 0;
for(int i=0; i < l1; i ++)
{
if(lexicon[a][i] != lexicon[b][i])
{
change ++;
}//end if
}//end for
}
if(change >= 2)
return 0;
if(change == 0)
return 2;
return 1;
}

void read()
{
len = 0;
while(scanf("%s", lexicon[len])!= EOF)
{
for(int i=0; i < len; i ++)
{
int type = lenword(i, len);
if(type == 1)
{
map[i][len] = 1;
map[len][i] = 1;
}
else if(type == 2 && i == 1)
{
map[i][len] = 3;
map[len][i] = 3;
equal = true;
}
}
len ++;
}
}
void ladder()
{
path[0] = 0;
pl = 1;
used[0] = 1;
load[0] = 0;
for(int i=0; i < pl; i ++)
{
if(flag)
break;
for(int j=0; j < len; j ++)
{
if(used[j] == 0 && map[path[i]][j] == 1 && j == 1)
{
path[pl] = j;
load[pl] = load[i] + 2;
printf("%d", load[pl]);
flag = true;
break;
}
if(used[j] == 0 && map[path[i]][j] == 1)
{
path[pl] = j;
load[pl] = load[i] + 1;
used[j] = 1;
pl ++;
}//end if
else if(used[j] == 0 && map[path[i]][j] == 3)
{
path[pl] = j;
load[pl] = load[i] + 1;
printf("%d", load[pl]);
flag = true;
pl ++;
break;
}//end if
}
}
if(!flag)
printf("%d", -1);
}

int main()
{
online();
read();
if(equal)
ladder();
else
printf("%d", -1);
return 0;
}


最坑爹是J题吧,当时做完这两道题的时候,是12点5分,还有将近两个半小时,当时看到J题的AC最多,其实我原先考虑过一遍,觉得这道题不简单,但是我看着这么多人通过,就冲动了。觉得是不是自己思维错了,又重新考虑了几遍,然后就一头栽进去了。这一进去就是比赛结束。后来出来的时候看到别人的解题报告。“此题可以首先分别扫描三个aspect,然后统计出每个aspect的最小值,再重新扫描一遍每一个team,如果该team的三个aspect都等于最小值,则计数加一,最后输出总的计数即可。复杂度O(n)。” 我发现真是坑爹的。“A team is called "special", if no other team's score is less than it in all three aspects. ”,这句话。。。。。。我不说啥了,我至今觉得仍然那些过了的人都是错误,而我的做法是正确的。

现在想来,自己当时犯得错误有:第一,不管别人做的怎么样,你自己才是最重要的,你不会做,再多的人做出来也没有用。第二,你的思维进入了误区,或者你的理解是对的,在大家都理解错的情况下,你还是要淡定的换一道题目。第三,不管怎么样,一定要把所有的题目都看一遍,我当时就看了这三道题目,其实还是有好几道题目,我是可以搞定的。第四,一个人的作为总是有限的,我在比赛中,缺乏对队友意见的考虑,如果当初他们叫我放弃的时候,我答应了,就不会这样子了。第五,5个小时里面,时间是很有限的,如果一道题没有想法的话,要果断的放弃,千万不要死磕啊。还有一方面的原因,我当时的目标就是做出来3道题,结果把自己给害了。

经验不足啊!下次接着努力吧,估计下次只能一个人去参赛了,他们都说找完工作就不搞了。

自己一个人学习算法,虽然中间走走停停的,前前后后算起来,也有半年时间了,突然间发现自己处于一个很尴尬的位置,难的题目还是搞不出来,简单的题目在大赛中,又是大家磕磕绊绊都能搞出来的,所以即使我很快的搞定前几道题目,最后剩下好几个小时搞后面的题目还是搞不出来,最后成绩还是那样,什么时候我才能接近那种大神的境界啊,那该是何等的快意啊!

这两次比赛的总结就先写到这吧,我觉得我应该去拜师,进一步提升一下自己。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: