写在前面
好久没更新公众号和博客了,因为最近在研究新的方向,所以很少发文。
笔者接触编程只有一年,这一年间主要研究启发式算法在运筹学中的应用。但是由于编程基础薄弱,在进一步研究复杂运筹学问题时发现基础算法不过关导致写出的代码运行速度很慢,因此很苦恼。所以决定这个暑假补习一下基础算法,主要是刷一些简单的ACM入门题。偶尔会发一些刷题笔记(偶尔!)。和作者有类似目标的同学可以一起交流共勉!
目前在看的教程:
北京理工大学ACM冬季培训课程
算法竞赛入门经典/刘汝佳编著.-2版
课程刷题点
Virtual Judge
下面记录下Day1的笔记。
Day1
简单看了课程第一讲,看了书的前两章左右。书中的习题比较简单所以暂时没做,目前在做第一讲的课后习题Day1。(上传密码xzmtql)
虽然去年下半年是最先接触C++入门的,但是用了几个月Java,现在C++已经忘完了。。。刷C++题也是为了找回C++的记忆吧。
现在发现确实很多东西都忘完了,所以刷第一题的时候就用了很久回忆C++、C的细节(和Java还是有点不同的),包括发现了一个以前都不知道的坑,debug了好久被迫咨询了下大佬:
C++的string不能通过C的scanf、printf输入输出。
如图这种nt的错误,对我这种C++入门、没有学过C,又在学过python后想用pringf的同学回过头来在C++代码中用printf的童鞋来讲,要多加小心。
D1T1-排名:
比较基础,主要是熟悉一下刷题流程,包括输入输出,EOF。
通过控制define转换输入输出方式(注意提交的时候一定要看清楚要不要注释掉啊,不然就多刷几个WA了):
文件中经常输入多个算例,有时有结束提示,有时没有,总之输入做成while(cin):
D1T1排名我的解:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
//#define LOCAL
struct Student
{
string id;
int score;
Student()
{
score = 0;
}
};
bool comp(Student x, Student y)
{
if (x.score != y.score)
return x.score > y.score;
else
return x.id < y.id;
}
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int stdNr = 0, titNr, passScore;
while (scanf("%d %d %d", &stdNr, &titNr, &passScore))
{
if (stdNr == 0) break;
int* titScore = new int[titNr + 5];
Student* students = new Student[stdNr + 5];
for (int i = 0; i < stdNr; i++)
students[i] = Student();
for (int i = 0; i < titNr; i++)
scanf("%d", titScore + i);
for (int i = 0; i < stdNr; i++)
{
string stdId;
int stdTitNr;
cin >> stdId >> stdTitNr;
students[i].id = stdId;
for (int j = 0; j < stdTitNr; j++)
{
int ts;
scanf("%d", &ts);
students[i].score += titScore[ts - 1];
}
}
sort(students, students + stdNr, comp);
int passId = 0;
for (passId = 0; passId < stdNr; passId++)
if (students[passId].score < passScore)
break;
printf("%d
", passId);
for (int i = 0; i < passId; i++)
cout << students[i].id << " " << students[i].score << endl;
}
return 0;
}
D1T2-魔法串
字符串的简单处理,本来打算暴力简单做一下,但是一直WA,百思不得其解,看了下别人的答案,发现有些人AC的答案也不一定对,但我的还是WA。。。万般无奈只能暂时放弃,有明白的同学可以交流下。
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;
// #define LOCAL
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
#endif
int caseNr;
scanf("%d", &caseNr);
for (int i = 0; i < caseNr; i++)
{
string str1, str2;
cin >> str1 >> str2;
int conversionNr;
cin >> conversionNr;
int table[24][24];
memset(table, 0, sizeof(table));
for (int j = 0; j < conversionNr; j++)
{
char c1, c2;
cin >> c1 >> c2;
table[c1 - 97][c2 - 97] = 1; // c1能转化为c2
}
int k = 0;
int happy = 1;
for (int j = 0; j < str1.length(); j++)
{
if (k == str2.length())
{
happy = 0;
break;
}
while (k < str2.length())
{
if (str1[j] == str2[k] || table[str2[k] - 97][str1[j] - 97] == 1)
{
k++;
break;
}
else
k++;
if (k == str2.length())
{
happy = 0;
break;
}
}
}
if (happy)
printf("Case #%d: happy
", i + 1);
else
printf("Case #%d: unhappy
", i + 1);
}
return 0;
}
最后贴上让人欲哭无泪的一堆WA和好不容易AC却很垃圾的解:
小结
本以为刷点简单的题目会很轻松,却没想到这么简单的题都浪费了这么多时间,果然还是基础太弱&&(!C++技能)。等29号考完试后要好好刷下题了。。。
关于每天刷题的代码和书籍教材资源我会上传到自己的上github,欢迎大家一起刷题~