PAT 1050 螺旋矩陣 (水題 然鵝)(又名:鹹魚和妖孽水題糾纏不清的故事)
題意簡單,寫題暴力。
但是曲折萬分,請諸位大佬當笑話看吧……。
請看版本一。
#include <iostream> #include <cmath> #include <string> #include <queue> #include <map> #include <vector> #include <stack> #include <algorithm> using namespace std; int mov[][2] = { 0,1,1,0,0,-1,-1,0 }; struct node { int x, y; }; bool cmp (int a,int b) { return a > b; } int n, m; int a[100005]; int mm[105][105]; bool check(node p) { if (p.x < 0 || p.x >= m || p.y < 0 || p.y >= n) return false; return true; } void dfs(node t,int cur,int dic) { for (int i = 0; i < 4; i++) { node p = t; p.x += mov[dic%4][0];p.y += mov[dic%4][1]; if (check(p) && mm[p.x][p.y] == 0) { mm[p.x][p.y] = a[cur]; dfs(p, cur + 1,dic); } else dic++; } } int main() { int t; while (cin >> t) { for(int i=0;i<t;i++) cin >> a[i]; sort(a, a + t, cmp); n = sqrt(t); while (t%n) { n--; } m = t / n; //cout << n << " " << m << endl; node p; p.x = p.y = 0; mm[p.x][p.y] = a[0]; dfs(p,1,0); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { cout << mm[i][j] << (j == n - 1 ? "\n" : " "); } } } //system("pause"); return 0; }
因為正在學回溯,所以自然而然的想,誒這個題回溯能不能寫啊,然後啪啦啪啦如上所示。其實還蠻開心的那個時候。之前還沒有註釋掉輸出來的n和m全錯了一次。
提交時間 | 狀態 | 分數 | 題目 | 編譯器 | 耗時 | 使用者 |
---|---|---|---|---|---|---|
2018/11/8 23:42:37 |
部分正確 |
24 | 1050 | C++ (g++) | 10 ms | 0413170432 |
測試點 | 結果 | 耗時 | 記憶體 |
---|---|---|---|
0 | 答案正確 | 3 ms | 512KB |
1 | 答案正確 | 3 ms | 512KB |
2 | 答案正確 | 3 ms | 512KB |
3 | 答案正確 | 3 ms | 512KB |
4 | 答案正確 | 3 ms | 376KB |
5 | 答案正確 | 3 ms | 508KB |
6 | 答案正確 | 10 ms | 1132KB |
7 | 段錯誤 | 9 ms | 520KB |
看到這個結果後想想看也是最多有1e4,遞迴本來就比較慢,更何況這個題目又不是不能迴圈解決。能迴圈解決的事情幹嘛要用遞迴呢,一邊笑自己蠢一邊改。呵呵呵,太天真了,那個時候萬萬想不到能有今天。
請看版本二
#include <iostream> #include <cmath> #include <string> #include <queue> #include <map> #include <vector> #include <stack> #include <algorithm> using namespace std; int mov[][2] = { 0,1,1,0,0,-1,-1,0 }; struct node { int x, y; }; bool cmp (int a,int b) { return a > b; } int n, m; int a[1000005]; int mm[10005][10005]; bool check(node p) { if (p.x < 0 || p.x >= m || p.y < 0 || p.y >= n) return false; return true; } int main() { int t; while (cin >> t) { for(int i=0;i<t;i++) scanf("%d",&a[i]); sort(a, a + t, cmp); n = sqrt(t); while (t%n) { n--; } m = t / n; //cout << n << " " << m << endl; node p; p.x = p.y = 0; mm[p.x][p.y] = a[0]; int dic = 0; node tt = p; for (int cur = 1; cur < t; cur++) { for (int i = 0; i < 4; i++) { node p = tt; p.x += mov[dic % 4][0]; p.y += mov[dic % 4][1]; if (check(p) && mm[p.x][p.y] == 0) { mm[p.x][p.y] = a[cur]; tt = p; break; } else dic++; } } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { printf("%d", mm[i][j]); printf(j == n - 1 ? "\n" : " "); } } } //system("pause"); return 0; }
提交時間 | 狀態 | 分數 | 題目 | 編譯器 | 耗時 | 使用者 |
---|---|---|---|---|---|---|
2018/11/8 23:52:07 |
部分正確 |
24 | 1050 | C++ (g++) | 37 ms | 0413170432 |
測試點 | 結果 | 耗時 | 記憶體 |
---|---|---|---|
0 | 答案正確 | 9 ms | 432KB |
1 | 答案正確 | 21 ms | 404KB |
2 | 答案正確 | 9 ms | 512KB |
3 | 答案正確 | 21 ms | 444KB |
4 | 答案正確 | 20 ms | 612KB |
5 | 答案正確 | 23 ms | 384KB |
6 | 答案正確 | 37 ms | 876KB |
7 | 執行超時 | 0 ms | 0KB |
執行超時了……超時了耶……因為迴圈四次就表示四個方向都判斷過了嘛……非常ok(然而並不需要)。
其實這個時候我們就可以想到因為他是順時針旋轉,所以我們只要判斷順時針的方向是否可以就行了,如果不行也就該出迴圈了。
之後我又嘗試了各種方法,包括紫書上的,對,我是先擴大了mm陣列的大小,然後用的紫書,這將是我將要講的第二件事情。第一件事情是關於變數定義陣列的事情。
這個時候我心態已然完全炸裂,網上各種找部落格,然後複製貼上上交,然後我看到一個和我寫的很像,但是區別僅有用變數開陣列的部落格,一交全對,然後我緩緩的把我的程式碼改成和他的程式碼類似的樣子,改一塊,上交一次,然後結果依然和上邊的沒有變化。
同志們,到這裡你們就可以看出來這個案例7該有多麼的妖孽!
此時已經接近凌晨1點,為了不打擾室友休息,無奈只能第二天繼續,然後一整個晚上就沒睡好。
一起床我就開始著急這個玩意,這個我把人家的往我的上改,改一次交一次,然而只改動了陣列的變數改成常量偏偏就錯了。
ok我們知道了是陣列在作怪,那麼為什麼陣列可以用變數定義呢。
C99加了……也就是說一些PTA的G++編譯器確實是讓過的……好的我們再看clang++,也可以,再看杭電的C++不可以。
驚了!這是什麼操作。
那麼我想紫書上的程式碼應當算是相當高明的,為什麼也會超時,然後我照著一位博主的部落格又敲了一遍,案例7依然超時。
這是什麼呢。
王德發!陣列大小還能影響時間的嗎?我的天哪!!
基礎差的哭出了聲我的天哪……還有這種事情orz
我這一整個晚上和一整個白天在糾結點什麼……
好的,今天本鹹魚的丟人故事就講到這裡了,我震驚了,你呢?
最後把AC的程式碼發一下吧……題目是真的水,案例是真的妖孽。
#include <iostream>
#include <iomanip>
#include <math.h>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(int a, int b)
{
return a > b;
}
int a[100005];
int mm[10005][1005];
int main()
{
int t;
scanf("%d", &t);
for (int i = 0; i < t; i++)
scanf("%d", &a[i]);
sort(a, a + t, cmp);
int n, m;
n = sqrt(t);
while (t%n)
{
n--;
}
m = t / n;
int cur = 0;
int x, y;
mm[1][1] = a[cur];
x = 1;
y = 1;
while (cur < t-1)
{
while (!mm[x][y + 1] && y+1 <= n)
mm[x][++y] = a[++cur];
while (!mm[x+1][y] && x+1 <= m)
mm[++x][y] = a[++cur];
while (!mm[x-1][y] && x-1 > 0)
mm[--x][y] = a[++cur];
while (!mm[x][y-1] && y-1 > 0)
mm[x][--y] = a[++cur];
}
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
printf("%d", mm[i][j]);
printf(j==n?"\n":" ");
}
}
system("pause");
}