# week 5 ## rock ### 解題思路 這題使用到了一個關鍵的技術 "單調堆疊",該技術目的是維護一個裡面元素遞增或遞減的 Stack,來達成題目的要求。此外,這題的空間複雜度可以進一步壓到 O(N),因為對於每個人,只要取得其拿到的石頭順序,便可以唯一決定她接下來的操作,故不需要在第一時間便像題目說明一樣直接做到底,而是可以先紀錄下一個人拿到的石頭順序就好,等到當前的人處理完後再處理下一個人即可。 時間複雜度: O(N^2) ### AC 程式 ```c # include <stdio.h> typedef long long int llt; void StackPush(llt *Stack, llt* Top, llt val) { (*Top)++; Stack[*Top]=val; } llt StackPop(llt *Stack, llt* Top) { if(*Top==-1) return -1; (*Top)--; return Stack[*Top+1]; } llt StackTop(llt *Stack, llt Top) { if(Top==-1) return -1; return Stack[Top]; } int main() { llt n; scanf("%lld", &n); llt a[n]; for(llt i=0;i<n;i++) { scanf("%lld", &a[i]); } llt Stack[n+10]; llt Top=-1; llt aSize=n; llt ans=1; while(1) { llt a_next[n]; llt a_nextSize=0; for(llt i=0;i<aSize;i++) { while(1) { if(StackTop(Stack, Top)==-1 || a[i]<=StackTop(Stack, Top)) break; a_next[a_nextSize]=StackPop(Stack, &Top); a_nextSize++; } StackPush(Stack, &Top, a[i]); } if(a_nextSize==0) break; for(llt i=0;i<a_nextSize;i++) { a[i]=a_next[i]; } aSize=a_nextSize; ans++; while(StackTop(Stack, Top)!=-1) { StackPop(Stack, &Top); } } printf("%lld\n", ans); return 0; } ``` ## Signal ### 解題思路 用陣列實作堆疊,遇到相同的就把stack頂端pop掉。 ### AC 程式 ```c= #include<stdio.h> #include<stdlib.h> #include<string.h> int main(){ char a[51],b[51]; scanf("%s",a); int length = strlen(a); b[0] = a[0]; int index = 1; for(int i = 1 ; i < length ; i++){ if(a[i]==b[index-1]){ index--; } else{ b[index] = a[i]; index++; } } b[index] = '\0'; printf("%s\n",b); return 0; } ``` ## Mood_graph ### 解題思路 直接跑過每一種可能,並記錄下最好的那一種印出來。 ### AC 程式 ```c= #include<stdio.h> #include<stdlib.h> int main(){ int n ; scanf("%d",&n); int *old_graph = (int *)malloc(n*sizeof(int)); int **new_graph = (int **)malloc(n*sizeof(int*)); for(int i = 0 ; i < n ; i++){ new_graph[i] = (int*)malloc(n*sizeof(int)); } for(int i = 0 ; i < n ; i++){ scanf("%d",&old_graph[i]); } int ans = 0,index = 0; for(int i = 0 ; i < n ; i++){//直接模擬每個點為山峰的情況 new_graph[i][i] = old_graph[i]; int sum = new_graph[i][i]; for(int j = i ; j > 0 ;j--){ if(old_graph[j-1] > new_graph[i][j]){ new_graph[i][j-1] = new_graph[i][j]; } else{ new_graph[i][j-1] = old_graph[j-1]; } sum += new_graph[i][j-1]; } for(int j = i ; j < n-1 ;j++){ if(old_graph[j+1] > new_graph[i][j]){ new_graph[i][j+1] = new_graph[i][j]; } else{ new_graph[i][j+1] = old_graph[j+1]; } sum += new_graph[i][j+1]; } } printf("%d\n",ans); for(int i = 0 ; i < n ; i++){ printf("%d ",new_graph[index][i]); } printf("\n"); return 0; } ```