这周又推迟了,考试真的可怕......不过还是必须得来总结,不然学了什么完全不知道,还会认为自己学了些东西很强的样子,果真没有比较就没有伤害。
python方面:
这周感觉还是老样子诶,没做出啥东西来,不过学会类啦,哈哈哈,本来就要学C++,真的不要太棒,面向对象的真的让我在C++方面也轻松了一些诶,而且虽然每天说好只学两个小时的python,但有时候打起代码来根本停不下来嘛。不扯了:
1. 首先对于python中的随机数,引用可以用import,不知道总结没有诶。。。不过还有另两种形式,
import __ from __ : 引用某个模块中的某个函数什么的
import __ as __ : 引用某个模块并且在代码中用 as 后的名字来使用
例如:
import random as r
a = r.randint(2, 6)
随机数是 random 其中可以用的是 uniform(__, __)(括号中给出两个数字的范围内的一个随机浮点数), randint(__, __)(括号里给出两个数字范围内的一个整型数, choice(某个序列)(随机取出这个序列中的一个元素)。不过发现可以这样给多个量同时用随机数哦:
n, m = random.choice([[2, 5], [6, 7], ['yuan', 4], [7, 'skjdfh']])
也是可以这样使用的
2. 然后收获最大的也就只有类了吧,和C++一样,存在公共与‘私有’, 为什么私有有 ’ ‘ , 因为它并不是真正的私有,而只是相当于把调用时的名字改变了而已。
例如:
class A():
def __printA(self):
print 'haha'
a = A()
这里直接用 a.printA() 是不行的,这里可以用 a._A__printA() 来调用。
3. 然后就是魔法方法主要是 __init__, __new__, __del__... 当然还有一些,不过我就对这些熟一些,__init__()可以让类在实例化前调用,感觉和初始化很像的感觉。
4. 还有字典可以通过键来调用函数,感觉很方便呢,虽然前面看了字典,但是还是缺少一些应用方面的知识,还是不行呢。
例如:
def print A():
print 'A'
a = { 1 : printA() }
a[1]
这样可以直接使用函数,感觉蛮方便的吧,总感觉这种组合后面挺有用的,总之现在了解为主。
还有 python 的浮点数精度不行,上次做一道题就说咋会错在浮点上呢,上网查了才知道原来是这样。。。
算法:
突然感觉这周没做啥,感觉学了还算是不短时间的算法,但才发现是自己太弱了,思想跟不上,同时也证明自己对算法的不熟悉,习惯于套公式的交题,一到变形题就瞬间怂了。
网易实习招聘有一道题:
一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。
输入描述:
输入包括两行: 第一行为整数n(1 ≤ n ≤ 50) 第二行为n个整数length[i](1024 ≤ length[i] ≤ 4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。
输出描述:
输出一个整数,表示最少需要处理的时间
输入例子:
5 3072 3072 7168 3072 1024
输出例子:
9216真的尴尬,开始以为要用什么特殊的方法解决,但结果是背包。。。我还自己总结过这个东西,结果还是没有看出来,思维真的差。不过对于这个题来说,我搞不太懂它的最大值,所以用的 vector 容器来作 dp 数组。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define MAX 50
int main()
{
int n, num, sum, data[MAX], ans;
vector<int>dp;
scanf("%d", &n);
sum = 0;
for (int i = 0; i < n; i++)
{
scanf("%d", &num);
sum += num / 1024;
data[i] = num / 1024;
}
for (int i = 0; i <= sum / 2; i++)
{
dp.push_back(0);
}
for (int i = 0; i < n; i++)//01背包的模板
{
for (int j = sum / 2; j >= data[i] ; j--)
{
dp[j] = max(dp[j - data[i]] + data[i], dp[j]);
}
}
printf("%d\n", (sum - dp[sum / 2]) * 1024);
return 0;
}
大致就是这样,简单的背包,所以接下来思维训练很重要。
然后还有一道题,是动态规划,沉迷学算法但是一些学过的东西却做不了,已经准备少接触新东西,先慢慢消化前面的东西才是正道。
再说一道也是在网易实习招聘中找到的:
小易拥有一个拥有魔力的手环上面有n个数字(构成一个环),当这个魔力手环每次使用魔力的时候就会发生一种奇特的变化:每个数字会变成自己跟后面一个数字的和(最后一个数字的后面一个数字是第一个),一旦某个位置的数字大于等于100就马上对100取模(比如某个位置变为103,就会自动变为3).现在给出这个魔力手环的构成,请你计算出使用k次魔力之后魔力手环的状态。
输入描述:
输入数据包括两行: 第一行为两个整数n(2 ≤ n ≤ 50)和k(1 ≤ k ≤ 2000000000),以空格分隔 第二行为魔力手环初始的n个数,以空格分隔。范围都在0至99.
输出描述:
输出魔力手环使用k次之后的状态,以空格分隔,行末无空格。
输入例子:
3 2 1 2 3
输出例子:
8 9 7刚开始以为是一个找规律的题,我觉得要模100, 可能是有一个循环吧,所以试着去做了一下,没做成功,不知道行不行得通。不过通过这个学到了矩阵快速幂,感觉和普通快速幂没有什么区别,但是意义上,矩阵可比那个数字复杂到哪去了。
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
#define MAX 55
class Solution {
public:
void mult(int A[MAX][MAX], int B[MAX][MAX], int C[MAX][MAX], int n)
{
int T[MAX][MAX];
memset(T, 0, sizeof(T));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
for (int k = 0; k < n; k++)
{
T[i][j] = (T[i][j] + A[i][k] * B[k][j]) % 100;
}
}
}
memcpy(C, T, sizeof(T));
}//矩阵相乘,并且覆盖掉原来的矩阵
void prep(int Ori[MAX][MAX], int Med[MAX][MAX], int n, int m)
{
if (!m)
{
memset(Med, 0, sizeof(int) * MAX * MAX);
for (int i = 0; i < n; i++)
{
Med[i][i] = 1;
}
}
else if (m % 2 == 0)
{
prep(Ori, Med, n, m / 2);
mult(Med, Med, Med, n);
}
else
{
prep(Ori, Med, n, m - 1);
mult(Ori, Med, Med, n);
}
}//由此来从最开始的矩阵开始处理,因为是一个递归的过程,想一下很好理解
vector<int> Deal(int m, vector<int>Seq)
{
int Ori[MAX][MAX], Med[MAX][MAX], n = Seq.size();
memset(Ori, 0, sizeof(Ori));
for (int i = 0; i < n; i++)
{
Ori[i][i] = Ori[i][(i + 1) % n] = 1;
}
prep(Ori, Med, n, m);
int sum;
vector<int> ans;
for (int i = 0; i < n; i++)
{
sum = 0;
for (int j = 0; j < n; j++)
{
sum = (sum + Seq[j] * Med[i][j]) % 100;
}
ans.push_back(sum);
}
return ans;
}
};
int main()
{
Solution deal;
int n, m, num;
cin >> n >> m;
vector<int>save;
for (int i = 0; i < n; i++)
{
cin >> num;
save.push_back(num);
}
vector<int>res;
res = deal.Deal(m, save);
for (int i = 0; i < n; i++)
{
if (!i)
{
cout << res[i];
}
else
{
cout << " " << res[i];
}
}
cout << "\n";
return 0;
}
矩阵快速幂意外的不是很难嘛,不过要灵活应用还是差得远呢。总的来说就是多练,这几周不准备学多少算法,要做的是,掌握好学过的算法。
还有很重要的是上周终于发现了一个自己一直弄错的问题。
sizeof() 求某个变量的大小的时候不能用它的形参,不然就会出错,真的十分可怕。就像上面代码中的一样
memset(Med, 0, sizeof(int) * MAX * MAX)
这里因为是形参,所以用 sizeof 只会得到一个整型的大小,所以我说为什么一直初始化错误,曾一度怀疑编译器的我是多么的傻。
看来还是那句话, 代码不会骗人。。。