nyoj 20 吝嗇的國度
阿新 • • 發佈:2019-02-07
還是《吝嗇的國度》,研讀了別人的較為高效的程式碼,無論是時間開銷,還是空間開銷都要小很多啊,截圖為證:
我的所有執行:
52ms的是我參照別人的寫的程式碼,時間開銷比我的小將近一半,記憶體開銷僅有我的五分之一。 不過,我自己又將他的改進了一下,雖然記憶體稍稍大了點,但時間開銷為40ms,排名第一啊,哈哈! WrongAnswer那次是因為忘了在遞迴中標記start,RuntimeError那次是為了除錯時檢視陣列內容,就把陣列開了100,結果除錯完忘了改回來,直接提交了,陣列越界,唉... 題目中要求從起始城市出發,輸出經過每個城市時,之前的那個城市的編號。這樣,相鄰兩個城市之間的關係實質上已經表示出來了,也就是說,存放之前城市編號的那個陣列,儲存了一個有向圖,如下圖所示: 輸入的測試資料為: 10 18 1010 33 710 41 91 88 61 29 5
紅色箭頭建立的的圖,即為陣列中存放之前城市編號所建立的有向圖。 按照這種思路建立有向圖,需要解決箭頭方向的問題,即確定哪個城市離出發城市更近。這裡有兩種方法: (一),建圖的過程中,不管箭頭方向,在整個圖建立完成之後,從出發城市開始調整箭頭方向。 (二),建圖的過程中,根據出發城市的位置調整箭頭方向,整個圖建立完成時,也就是一個正確的有向圖。 思路(一)也就是高人的思路,程式碼如下: [cpp] view plaincopyprint?
[cpp] view plaincopyprint?
52ms的是我參照別人的寫的程式碼,時間開銷比我的小將近一半,記憶體開銷僅有我的五分之一。 不過,我自己又將他的改進了一下,雖然記憶體稍稍大了點,但時間開銷為40ms,排名第一啊,哈哈! WrongAnswer那次是因為忘了在遞迴中標記start,RuntimeError那次是為了除錯時檢視陣列內容,就把陣列開了100,結果除錯完忘了改回來,直接提交了,陣列越界,唉... 題目中要求從起始城市出發,輸出經過每個城市時,之前的那個城市的編號。這樣,相鄰兩個城市之間的關係實質上已經表示出來了,也就是說,存放之前城市編號的那個陣列,儲存了一個有向圖,如下圖所示: 輸入的測試資料為:
紅色箭頭建立的的圖,即為陣列中存放之前城市編號所建立的有向圖。 按照這種思路建立有向圖,需要解決箭頭方向的問題,即確定哪個城市離出發城市更近。這裡有兩種方法: (一),建圖的過程中,不管箭頭方向,在整個圖建立完成之後,從出發城市開始調整箭頭方向。 (二),建圖的過程中,根據出發城市的位置調整箭頭方向,整個圖建立完成時,也就是一個正確的有向圖。 思路(一)也就是高人的思路,程式碼如下: [cpp] view plaincopyprint?
- #include <stdio.h>
- #include <memory.h>
- int map[100005];
- void Adjust(int currentCity)
- {
- int priorCity = map[currentCity];
- if (priorCity != 0)
- {
- Adjust(priorCity);
- map[priorCity] = currentCity;
- }
- }
- int main()
- {
- int i, testNum, cityNum, startCity, cityA, cityB;
- scanf("%d", &testNum);
- while
- {
- scanf("%d%d", &cityNum, &startCity);
- memset(map, 0, sizeof(int)*cityNum + 1);
- for (i = 1; i < cityNum; i++)
- {
- scanf("%d%d", &cityA, &cityB);
- if (map[cityB] == 0)
- {
- map[cityB] = cityA;
- }
- else
- {
- Adjust(cityA);
- map[cityA] = cityB;
- }
- }
- Adjust(startCity);
- map[startCity] = - 1;
- for (i = 1; i < cityNum; i++)
- {
- printf("%d ", map[i]);
- }
- printf("%d\n", map[i]);
- }
- return 0;
- }
#include <stdio.h>
#include <memory.h>
int map[100005];
void Adjust(int currentCity)
{
int priorCity = map[currentCity];
if (priorCity != 0)
{
Adjust(priorCity);
map[priorCity] = currentCity;
}
}
int main()
{
int i, testNum, cityNum, startCity, cityA, cityB;
scanf("%d", &testNum);
while (testNum-- != 0)
{
scanf("%d%d", &cityNum, &startCity);
memset(map, 0, sizeof(int)*cityNum + 1);
for (i = 1; i < cityNum; i++)
{
scanf("%d%d", &cityA, &cityB);
if (map[cityB] == 0)
{
map[cityB] = cityA;
}
else
{
Adjust(cityA);
map[cityA] = cityB;
}
}
Adjust(startCity);
map[startCity] = - 1;
for (i = 1; i < cityNum; i++)
{
printf("%d ", map[i]);
}
printf("%d\n", map[i]);
}
return 0;
}
思路(二)是我自己的,因為我發現不考慮方向建立圖時,會出現方向的多次調整,影響效率,所以我就想在建立圖的過程中就考慮方向,程式碼如下:[cpp] view plaincopyprint?
- #include <stdio.h>
- #include <memory.h>
- int map[100005];
- bool flag[100005];
- void AdjustIncludeStart(int currentCity)
- {
- int priorCity = map[currentCity];
- if (priorCity != 0)
- {
- AdjustIncludeStart(priorCity);
- map[priorCity] = currentCity;
- flag[priorCity] = true;
- }
- }
- void AdjustExcludeStart(int currentCity)
- {
- int priorCity = map[currentCity];
- if (priorCity != 0)
- {
- AdjustExcludeStart(priorCity);
- map[priorCity] = currentCity;
- }
- }
- int main()
- {
- int i, testNum, cityNum, startCity, cityA, cityB;
- scanf("%d", &testNum);
- while (testNum-- != 0)
- {
- scanf("%d%d", &cityNum, &startCity);
- memset(map, 0, sizeof(int)*cityNum + 1);
- memset(flag, false, sizeof(bool)*cityNum + 1);
- map[startCity] = - 1;
- flag[startCity] = true;
- for (i = 1; i < cityNum; i++)
- {
- scanf("%d%d", &cityA, &cityB);
- if (flag[cityA])
- {
- if (map[cityB] != 0)
- {
- AdjustIncludeStart(cityB);
- }
- map[cityB] = cityA;
- flag[cityB] = true;
- }
- elseif (flag[cityB])
- {
- if (map[cityA] != 0)
- {
- AdjustIncludeStart(cityA);
- }
- map[cityA] = cityB;
- flag[cityA] = true;
- }
- else
- {
- if (map[cityB] == 0)
- {
- map[cityB] = cityA;
- }
- else
- {
- AdjustExcludeStart(cityA);
- map[cityA] = cityB;
- }
- }
- }
- for (i = 1; i < cityNum; i++)
- {
- printf("%d ", map[i]);
- }
- printf("%d\n", map[i]);
- }
- return 0;
- }