重复局面
问题:给出若干棋盘的表达,字符矩阵形式,判断每个棋盘局面出现的次数
我的思路:
字符串对比,但是感觉每一个棋盘和前面每一个比较太重复,太麻烦。想到可以只对比棋子的位置,每个棋子维护一个位置矩阵,然后在读入的时候,记录下所有棋子每次的坐标值,然后,从第二个棋盘开始,每个都和前面每个棋子对比,看是否一样。不一样就break,记为1,然后如果能走到最后一个棋子,则次数加一。
OMG,好神经啊,深思熟虑之后想的什么狗屎方法啊,麻烦死了,还不如一开始的重复方法。
优秀思路:
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main(){
int num;
cin >> num;
char chess[64];
vector<int> ans(num);
map<string, int> status_map;
for(int i = 0; i < num; i++){
for (int j = 0; j < 64; j++){
cin >> chess[j];
}
if(status_map.count(chess)){
status_map[chess] ++;
else
status_map[chess] = 1;
ans[i] = status_map[chess];
}
for(int i = 0 ; i < num; i++)
cout << ans[i] << endl;
return 0;
}
原来博主在读取一个棋盘计算完次数就输出了出现次数,感觉和题目要求不太一样,但其实提交之后是100分,但就是觉得不舒服,所以又用了一个vector存储结果,最后一并输出。
get:
一开始用数组,可能是初始化的什么的问题,提交就错误,换成vector就对了,那么以后遇到长度不一定的,尽量就用vector吧。
***直接用每个棋盘的表达式作为键,次数作为值,每次调用map[].count()可以获取该键值对的个数。
OMG,真的好牛,用了一个map,完美解决,也是第一次知道map还能这样用。我这知识也太贫瘠了,wuwuwuwu。
一些map的知识
#include <map>
using namespace std;
map<KeyType, ValueType> myMap;
加入
myMap[key] = value;
删除
myMap.erase(key);
检查键是否存在
if (myMap.count(key) > 0) {
// 键存在
}
auto it = myMap.find(key);
if (it != myMap.end()) {
// 键存在
}
遍历
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
cout << it->first << " : " << it->second << endl;
}
矩阵运算
题目
一个向量×三个矩阵连乘,输出最后的结果
思路
最初的思路竟然是矩阵连乘,动态规划,真神经啊,三个矩阵,至于吗?但是确实有一点想到点上。
优秀思路
确实是要找一个最优的顺序,手动就可以了,毕竟就三个矩阵。根据矩阵运算的复杂度分析一下,这里看了其他博主的
CCF CSP题解:矩阵运算(202305-2)
所以就是单纯的矩阵运算
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n,d;
cin >> n >> d;
vector<vector<long long> > Q(n,vector<long long>(d)), K(n,vector<long long>(d)), V(n,vector<long long>(d));
vector<long long> W(n);
for(int i = 0; i < n; i++){
for(int j = 0; j < d; j++){
cin >> Q[i][j];
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < d; j++){
cin >> K[i][j];
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < d; j++){
cin >> V[i][j];
}
}
for(int i = 0; i < n; i++){
cin >> W[i];
}
// K转置 * V
vector<vector<long long> > t(n,vector<long long>(d));
for(int i = 0; i < d; i++){
for(int j = 0; j < d; j++){
for(int k = 0; k < n; k++ ){
t[i][j] += K[k][i] * V[k][j];
}
}
}
// Q*
vector<vector<long long> > ans(n,vector<long long>(d));
for(int i = 0; i < n; i++){
for(int j = 0; j < d; j++){
for(int k = 0; k < d; k++ ){
ans[i][j] += Q[i][k] * t[k][j];
}
}
}
// W*
long long out;
for(int i = 0; i < n; i++){
for(int j = 0; j < d; j++){
cout << ans[i][j] * W[i] << " ";
}
cout << endl;
}
return 0;
}
get
矩阵运算的话,一般都往顺序上想想,复杂度会降。
复杂度和矩阵的规模有关系,[i,k] X [k,j] 复杂度 = i * k *j
然后矩阵的运算是三层循环,i,j,k,前两层一个是左行,一个是右列,k是控制每行每列的的每一个
正常:ans[i][j] += Q[i][k] * t[k][j];
转置:ans[i][j] += Q[k][i] * t[k][j]; (行列互换)