1. 程式人生 > >nyoj 20 吝嗇的國度

nyoj 20 吝嗇的國度

還是《吝嗇的國度》,研讀了別人的較為高效的程式碼,無論是時間開銷,還是空間開銷都要小很多啊,截圖為證: 我的所有執行:

52ms的是我參照別人的寫的程式碼,時間開銷比我的小將近一半,記憶體開銷僅有我的五分之一。 不過,我自己又將他的改進了一下,雖然記憶體稍稍大了點,但時間開銷為40ms,排名第一啊,哈哈! WrongAnswer那次是因為忘了在遞迴中標記start,RuntimeError那次是為了除錯時檢視陣列內容,就把陣列開了100,結果除錯完忘了改回來,直接提交了,陣列越界,唉... 題目中要求從起始城市出發,輸出經過每個城市時,之前的那個城市的編號。這樣,相鄰兩個城市之間的關係實質上已經表示出來了,也就是說,存放之前城市編號的那個陣列,儲存了一個有向圖,如下圖所示: 輸入的測試資料為:
10 18 1010 33 710 41 91 88 61 29 5
紅色箭頭建立的的圖,即為陣列中存放之前城市編號所建立的有向圖。 按照這種思路建立有向圖,需要解決箭頭方向的問題,即確定哪個城市離出發城市更近。這裡有兩種方法: (一),建圖的過程中,不管箭頭方向,在整個圖建立完成之後,從出發城市開始調整箭頭方向。 (二),建圖的過程中,根據出發城市的位置調整箭頭方向,整個圖建立完成時,也就是一個正確的有向圖。 思路(一)也就是高人的思路,程式碼如下: [cpp] view plaincopyprint?
  1. #include <stdio.h>
  2. #include <memory.h>
  3. int map[100005];  
  4. void Adjust(int currentCity)  
  5. {  
  6.     int priorCity = map[currentCity];  
  7.     if (priorCity != 0)  
  8.     {  
  9.         Adjust(priorCity);  
  10.         map[priorCity] = currentCity;  
  11.     }  
  12. }  
  13. int main()  
  14. {  
  15.     int i, testNum, cityNum, startCity, cityA, cityB;  
  16.     scanf("%d", &testNum);  
  17.     while
     (testNum-- != 0)  
  18.     {  
  19.         scanf("%d%d", &cityNum, &startCity);  
  20.         memset(map, 0, sizeof(int)*cityNum + 1);  
  21.         for (i = 1; i < cityNum; i++)  
  22.         {  
  23.             scanf("%d%d", &cityA, &cityB);  
  24.             if (map[cityB] == 0)  
  25.             {  
  26.                 map[cityB] = cityA;  
  27.             }  
  28.             else
  29.             {  
  30.                 Adjust(cityA);  
  31.                 map[cityA] = cityB;  
  32.             }  
  33.         }  
  34.         Adjust(startCity);  
  35.         map[startCity] = - 1;  
  36.         for (i = 1; i < cityNum; i++)  
  37.         {  
  38.             printf("%d ", map[i]);  
  39.         }  
  40.         printf("%d\n", map[i]);  
  41.     }  
  42.     return 0;  
  43. }  
#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?
  1. #include <stdio.h>
  2. #include <memory.h>
  3. int map[100005];  
  4. bool flag[100005];  
  5. void AdjustIncludeStart(int currentCity)  
  6. {  
  7.     int priorCity = map[currentCity];  
  8.     if (priorCity != 0)  
  9.     {  
  10.         AdjustIncludeStart(priorCity);  
  11.         map[priorCity] = currentCity;  
  12.         flag[priorCity] = true;  
  13.     }  
  14. }  
  15. void AdjustExcludeStart(int currentCity)  
  16. {  
  17.     int priorCity = map[currentCity];  
  18.     if (priorCity != 0)  
  19.     {  
  20.         AdjustExcludeStart(priorCity);  
  21.         map[priorCity] = currentCity;  
  22.     }  
  23. }  
  24. int main()  
  25. {  
  26.     int i, testNum, cityNum, startCity, cityA, cityB;  
  27.     scanf("%d", &testNum);  
  28.     while (testNum-- != 0)  
  29.     {  
  30.         scanf("%d%d", &cityNum, &startCity);  
  31.         memset(map, 0, sizeof(int)*cityNum + 1);  
  32.         memset(flag, falsesizeof(bool)*cityNum + 1);  
  33.         map[startCity] = - 1;  
  34.         flag[startCity] = true;  
  35.         for (i = 1; i < cityNum; i++)  
  36.         {  
  37.             scanf("%d%d", &cityA, &cityB);  
  38.             if (flag[cityA])  
  39.             {  
  40.                 if (map[cityB] != 0)  
  41.                 {  
  42.                     AdjustIncludeStart(cityB);  
  43.                 }  
  44.                 map[cityB] = cityA;  
  45.                 flag[cityB] = true;  
  46.             }  
  47.             elseif (flag[cityB])  
  48.             {  
  49.                 if (map[cityA] != 0)  
  50.                 {  
  51.                     AdjustIncludeStart(cityA);  
  52.                 }  
  53.                 map[cityA] = cityB;  
  54.                 flag[cityA] = true;  
  55.             }  
  56.             else
  57.             {  
  58.                 if (map[cityB] == 0)  
  59.                 {  
  60.                     map[cityB] = cityA;  
  61.                 }  
  62.                 else
  63.                 {  
  64.                     AdjustExcludeStart(cityA);  
  65.                     map[cityA] = cityB;  
  66.                 }  
  67.             }  
  68.         }  
  69.         for (i = 1; i < cityNum; i++)  
  70.         {  
  71.             printf("%d ", map[i]);  
  72.         }  
  73.         printf("%d\n", map[i]);  
  74.     }  
  75.     return 0;  
  76. }