由於第二遍做,思路還是有的。
//第一次提交
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
const int N = 1e5+7;
vector<vector<int> >vec(4);//不定義外層大小出錯
unordered_map<int, int>mp;//提交後將bool改成int
int main() {
int T;
scanf_s("%d", &T);
while (T--) {
for (int i = 0; i < vec.size(); i++) {//提交後發現的第一個問題
vec[i].clear();
}
//vec.clear();
int n;
scanf_s("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < 4; j++) {
int value;
scanf_s("%d", &value);
vec[j].push_back(value);
}
}
/*卡住*/
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
mp[vec[0][i] + vec[1][j]]++;//提交後發現的第二個問題 ,bool
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (mp.count(-(vec[2][i] + vec[3][j])))ans+= mp[-(vec[2][i] + vec[3][j])];//注意
}
}
printf("%d\n", ans);
if(T)printf("\n");
}
return 0;
}
一.vector二維數組
- 聲明一個動態二維數組一定要定義它的外層大小。
- 如果指定內外層向量的大小,就可用operator[]進行讀寫;如果只指定外層向量大小,只能用push_back()函數進行寫,不能用operator[]進行讀和寫。 (存疑)
vector<vector<int> >vec(4);
vector<vector<int> >b(10, vector<int>(5));
二.思路波動過程
思路是有的,使用動態數組存儲輸入值,map將數字對bool值映射,當時想的是若該數字和存在bool值即爲1。提交後答案非常小,發現忽略了集合a+集合b出現的數字可能重複。
vector動態數組未定義外層大小,出錯。同時發現,二維數組不能簡單地清空。
for (int i = 0; i < vec.size(); i++) {
vec[i].clear();
}
以上兩個問題解決後,卡了比較長的時間。
if (mp.count(-(vec[2][i] + vec[3][j])))ans+= mp[vec[2][i] + vec[3][j]];
這裏完成的是若在cd中找到ab中的相反數,則加上該數值已有的組合數(ab兩集合中),若不在mp中添加負號,則mp映射出來的就不是該相反數對應的值,大概率重新定義一個映射,值爲0。-(c+d)=a+b,這裏要多想一下。
所有問題解決後時間超限,看視頻發現是mp.count操作佔用了大量時間。使用mp.count()非常順應我的思路,好理解,刪去後可能不好閱讀,事實上若該值對應相反數不存在,加上的也是0,不影響答案。
修改好能改的一切後答案錯誤75%,判斷錯誤大概率是因爲使用的vector數組及其各種操作函數。由於一開始只定義了外層大小,上網搜索若指定內外層大小可以使用operator[]進行讀和寫,使用如下操作程序錯誤無法運行。
vector<vector<int> >vec(4,vector<int>(4007));
for (int i = 0; i < n; i++) {
for (int j = 0; j < 4; j++) {
cin>>vec[j][i];
}
}
放棄,暫時認爲vector的各種操作拖慢了時間,還是用a[][]直接賦值完事,也不用clear()。
此外,學長提示這種計數問題用long long比較好,不用會爆掉。暫時還不理解,先記住,因爲不用確實錯誤25%。
- 2020/1/27 a[][]通過
- 2020/2/18 vector