生活随笔
收集整理的這篇文章主要介紹了
算法设计与分析-实验2
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題 A: algorithm-迷宮游戲 題目描述 你來到一個迷宮前。該迷宮由若干個房間組成,每個房間都有一個得分,第一次進入這個房間,你就可以得到這個分數。還有若干雙向道路連結這些房間,你沿著這些道路從一個房間走到另外一個房間需要一些時間。游戲規定了你的起點和終點房間,你首要目標是從起點盡快到達終點,在滿足首要目標的前提下,使得你的得分總和盡可能大。現在問題來了,給定房間、道路、分數、起點和終點等全部信息,你能計算在盡快離開迷宮的前提下,你的最大得分是多少么? 輸入 第一行4個整數n (<=500), m, start, end。n表示房間的個數,房間編號從0到(n - 1),m表示道路數,任意兩個房間之間最多只有一條道路,start和end表示起點和終點房間的編號。 第二行包含n個空格分隔的正整數(不超過600),表示進入每個房間你的得分。 再接下來m行,每行3個空格分隔的整數x, y, z (0<z<=200)表示道路,表示從房間x到房間y(雙向)的道路,注意,最多只有一條道路連結兩個房間,你需要的時間為z。 輸入保證從start到end至少有一條路徑。 輸出 占一行,分別最短時間和相應的最大得分,中間用空格隔開。 樣例輸入 Copy 3 2 0 2 1 2 3 0 1 10 1 2 11 樣例輸出 Copy 21 6
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
using namespace std
; #define Int __int64
#define INF 0x3f3f3f3f const int MAXN
= 555 ;
int n
, m
, s
, e
; int maze
[ MAXN
] [ MAXN
] ;
int dis
[ MAXN
] ;
bool vis
[ MAXN
] ;
int score
[ MAXN
] ;
int ans
[ MAXN
] ; void init ( ) { for ( int i
= 0 ; i
< n
; i
++ ) { for ( int j
= 0 ; j
< n
; j
++ ) { if ( i
== j
) maze
[ i
] [ j
] = 0 ; else maze
[ i
] [ j
] = INF
; } } memset ( dis
, 0 , sizeof ( dis
) ) ; memset ( vis
, false , sizeof ( vis
) ) ; memset ( ans
, false , sizeof ( ans
) ) ;
} void Dijkstra ( ) { for ( int i
= 0 ; i
< n
; i
++ ) { scanf ( "%d" , & score
[ i
] ) ; } int u
, v
, w
; for ( int i
= 0 ; i
< m
; i
++ ) { scanf ( "%d %d %d" , & u
, & v
, & w
) ; if ( w
< maze
[ u
] [ v
] ) { maze
[ u
] [ v
] = w
; maze
[ v
] [ u
] = w
; } } for ( int i
= 0 ; i
< n
; i
++ ) { dis
[ i
] = maze
[ s
] [ i
] ; if ( i
!= s
) ans
[ i
] = score
[ s
] + score
[ i
] ; else ans
[ i
] = score
[ i
] ; } for ( int i
= 0 ; i
< n
; i
++ ) { int pos
, Min
= INF
; for ( int a
= 0 ; a
< n
; a
++ ) { if ( vis
[ a
] ) continue ; if ( dis
[ a
] < Min
) { Min
= dis
[ a
] ; pos
= a
; } } vis
[ pos
] = true ; for ( int a
= 0 ; a
< n
; a
++ ) { if ( maze
[ pos
] [ a
] < INF
) { if ( dis
[ a
] > dis
[ pos
] + maze
[ pos
] [ a
] ) { dis
[ a
] = dis
[ pos
] + maze
[ pos
] [ a
] ; ans
[ a
] = ans
[ pos
] + score
[ a
] ; } else if ( ( dis
[ a
] == dis
[ pos
] + maze
[ pos
] [ a
] ) && ( ans
[ a
] < ans
[ pos
] + score
[ a
] ) && pos
!= a
) { ans
[ a
] = ans
[ pos
] + score
[ a
] ; } else { continue ; } } } }
}
int main ( )
{ while ( scanf ( "%d %d %d %d" , & n
, & m
, & s
, & e
) != EOF ) { init ( ) ; Dijkstra ( ) ; printf ( "%d %d\n" , dis
[ e
] , ans
[ e
] ) ; } return 0 ;
}
問題 B: algorithm-Homework [命題人 : 080063] 時間限制 : 1.000 sec 內存限制 : 128 MB
題目描述 臨近開學了,大家都忙著收拾行李準 備返校,但 I_Love_C 卻不為此擔心! 因為他的心思全在暑假作業上:目前為止還未開動。 暑假作業是很多張試卷,我們這些從試卷里爬出來的人都知道,卷子上的題目有選擇題、填空題、簡答題、證明題等。而做選擇題的好處就在于工作量很少,但又因為選擇題題目都普遍很長。如果有 5 張試卷,其中 4 張是選擇題,最后一張是填空題,很明顯做最后一張所花的時間要比前 4 張長很多。但如果你只做了選擇題,雖然工作量很少,但表面上看起來也已經做了4/5的作業了。 I_Love_C決定就用這樣的方法來蒙混過關,他統計出了做完每一張試卷所需的時間以及它做完后能得到的價值(按上面的原理,選擇題越多價值當然就越高咯)。 現在就請你幫他安排一下,用他僅剩的一點時間來做最有價值的作業。 輸入 測試數據包括多組。每組測試數據以兩個整數 M,N(1<M<20,1<N<10000) 開頭,分別表示試卷的數目和 I_Love_C 剩下的時間。接下來有 M 行,每行包括兩個整數 T,V(1<T<N,1<V<10000)分別表示做完這張試卷所需的時間以及做完后能得到的價值,輸入以 0 0 結束。 輸出 對應每組測試數據輸出 I_Love_C 能獲得的最大價值。保留小數點 2 位 提示:float 的精度可能不夠,你應該使用 double 類型。 樣例輸入 Copy 4 20 4 10 5 22 10 3 1 2 0 0 樣例輸出 Copy 37.00
#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
using namespace std
; struct Paper
{ int time
; int value
; double perValue
; bool operator < ( const Paper
& h
) const { return ( h
. perValue
< perValue
) ; }
} ; int main ( )
{ int M
, N
; while ( cin
>> M
>> N
&& ( M
|| N
) ) { vector
< Paper
> list ( M
) ; for ( int i
= 0 ; i
< M
; ++ i
) { cin
>> list
[ i
] . time
>> list
[ i
] . value
; list
[ i
] . perValue
= list
[ i
] . value
/ double ( list
[ i
] . time
) ; } sort ( list
. begin ( ) , list
. end ( ) ) ; double sum
= 0 ; for ( int i
= 0 ; i
< M
; ++ i
) { if ( N
>= list
[ i
] . time
) { sum
+ = list
[ i
] . value
; N
- = list
[ i
] . time
; } else { sum
+ = list
[ i
] . perValue
* N
; break ; } } cout
<< setiosflags ( ios
:: fixed
) << setprecision ( 2 ) << sum
<< endl
; } return 0 ;
}
問題 C: algorithm-哈夫曼編碼 [命題人 : 080063] 時間限制 : 1.000 sec 內存限制 : 128 MB
題目描述 給定一只含有小寫字母的字符串;輸出其哈夫曼編碼的長度 輸入 第一行一個整數T,代表樣例的個數,接下來T行,每行一個字符串,0<T<=2000,字符串長度0<L<=1500. 輸出 對于每個字符串,輸出其哈夫曼編碼長度 樣例輸入 Copy 3 hrvsh lcxeasexdphiopd mntflolfbtbpplahqolqykrqdnwdoq 樣例輸出 Copy 10 51 115
#include <iostream>
#include <queue>
#include <string.h>
using namespace std
;
int main ( )
{ int t
; cin
>> t
; while ( t
-- ) { char s
[ 2000 ] ; cin
>> s
; int fre
[ 26 ] = { 0 } ; int len
= strlen ( s
) ; for ( int i
= 0 ; i
< len
; i
++ ) { fre
[ s
[ i
] - 'a' ] ++ ; } priority_queue
< int , vector
< int > , greater
< int > > q
; for ( int i
= 0 ; i
< 26 ; i
++ ) { if ( fre
[ i
] > 0 ) { q
. push ( fre
[ i
] ) ; } } int sum
= 0 ; while ( q
. size ( ) >= 2 ) { int a
= q
. top ( ) ; q
. pop ( ) ; int b
= q
. top ( ) ; q
. pop ( ) ; sum
+ = ( a
+ b
) ; q
. push ( a
+ b
) ; } cout
<< sum
<< endl
; } return 0 ;
}
問題 D: algorithm-汽車費用 [命題人 : 080063] 時間限制 : 1.000 sec 內存限制 : 128 MB
題目描述 一個特別的單行街道在每公里處有一個汽車站。顧客根據他們乘坐汽車的公里使來付費。例如下表就是一個費用的單子。沒有一輛車子行駛超過10公里,一個顧客打算行駛n公里(1<=n<100),它可以通過無限次的換車來完成旅程。最后要求費用最少。 輸入 第一行十個整數分別表示行走1到10公里的費用(<=500)。注意這些數并無實際的經濟意義,即行駛10公里費用可能比行駛一公里少。第二行一個整數n表示,旅客的總路程數。 輸出 僅一個整數表示最少費用。
樣例輸入 Copy 12 21 31 40 49 58 69 79 90 101 15 樣例輸出 Copy 147
#include <iostream>
#include <vector>
using namespace std
;
int main ( ) { vector
< int > res
= vector
< int > ( 11 , 0 ) ; for ( int i
= 1 ; i
<= 10 ; i
++ ) { cin
>> res
[ i
] ; } int m
; cin
>> m
; vector
< int > ans
= vector
< int > ( m
+ 1 , 10000 ) ; ans
[ 0 ] = 0 ; for ( int i
= 1 ; i
<= 10 ; i
++ ) { for ( int j
= i
; j
<= m
; j
++ ) { ans
[ j
] = min ( ans
[ j
] , ans
[ j
- i
] + res
[ i
] ) ; } } cout
<< ans
[ m
] ;
}
問題 E: algorithm-八皇后問題 [命題人 : 080063] 時間限制 : 1.000 sec 內存限制 : 128 MB
題目描述 努比亞和蘇丹沒有子女,所以他要從一些有集成資格的繼承者中挑選一個出來繼承王位。他希望這個繼承者足夠聰明,所以他準備了一個西洋棋盤,上面的每個格子中均有一個 1-99 的數字。他又準備了 8 個皇后棋子。 8 皇后的規則就是不能有任何棋子同行或者同列或者同斜線,在滿足這個規則的同時,王位繼承者還需要讓 8 個皇后所在的位置的數字的和是最大的。 輸入 輸入一個數字 k(k≤20),代表棋盤的數量。 接下來有 k 個棋盤,每個棋盤有 64 個數字,分成 8 行 8 列輸入,具體可見樣例,每一個數字均小于 100。 輸出 每一個棋盤對應輸出最大的數值, 一共輸出 k行 樣例輸入 Copy 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 48 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 樣例輸出 Copy 260
#include <iostream>
#include <vector>
using namespace std
;
int result
;
void dfs ( vector
< vector
< int > > & m
, vector
< bool > res
, vector
< pair
< int , int > > check
, int start
, int n
, int sum
) { if ( n
== 8 ) { result
= max ( result
, sum
) ; return ; } bool flag
= 1 ; for ( int i
= 0 ; i
< 8 ; i
++ ) { if ( ! res
[ i
] ) { flag
= 1 ; for ( int j
= 0 ; j
< check
. size ( ) ; j
++ ) { if ( start
+ i
== check
[ j
] . first
+ check
[ j
] . second
|| start
- i
== check
[ j
] . first
- check
[ j
] . second
) { flag
= 0 ; break ; } } if ( flag
) { res
[ i
] = 1 ; check
. push_back ( make_pair ( start
, i
) ) ; dfs ( m
, res
, check
, start
+ 1 , n
+ 1 , sum
+ m
[ start
] [ i
] ) ; check
. pop_back ( ) ; res
[ i
] = 0 ; } } }
}
int main ( ) { vector
< bool > res
= vector
< bool > ( 8 , 0 ) ; vector
< pair
< int , int > > check
; int len
; cin
>> len
; while ( len
-- ) { result
= 0 ; vector
< vector
< int > > sex
= vector
< vector
< int > > ( 8 , vector
< int > ( 8 , 0 ) ) ; for ( int i
= 0 ; i
< 8 ; i
++ ) { for ( int j
= 0 ; j
< 8 ; j
++ ) { cin
>> sex
[ i
] [ j
] ; } } dfs ( sex
, res
, check
, 0 , 0 , 0 ) ; cout
<< result
<< endl
; } return 0 ;
}
問題 F: algorithm-法師康的工人 [命題人 : 080063] 時間限制 : 1.000 sec 內存限制 : 128 MB
題目描述 三個法師康的工人每天早上6點到工廠開始到三條產品生產線上組裝桔子手機。第一個工人在200時刻開始(從6點開始計時,以秒作為單位)在生產線上開始生產,一直到1000時刻。第二個工人,在700時刻開始,在1100時刻結束。第三個工人從1500時刻工作到2100時刻。期間最長至少有一個工人在生產線上工作的連續時間為900秒(從200時刻到1100時刻),而最長的無人生產的連續時間(從生產開始到生產結束)為400時刻(1100時刻到1500時刻)。 你的任務是用一個程序衡量N個工人在N條產品線上的工作時間列表(1≤N≤5000,以秒為單位)。 ·最長的至少有一個工人在工作的時間段 ·最長的無人工作的時間段(從有人工作開始計) 輸入 輸入第1行為一個整數N,第2-N+1行每行包括兩個均小于1000000的非負整數數據,表示其中一個工人的生產開始時間與結束時間。 輸出 輸出為一行,用空格分隔開兩個我們所求的數。 樣例輸入 Copy 3 200 1000 700 1100 1500 2100 樣例輸出 Copy 900 400
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std
;
bool compare ( pair
< int , int > a
, pair
< int , int > b
) { if ( a
. first
== b
. first
) return a
. second
< b
. second
; return a
. first
< b
. first
;
}
int main ( ) { int a
; cin
>> a
; vector
< pair
< int , int > > res
= vector
< pair
< int , int > > ( a
) ; for ( int i
= 0 ; i
< a
; i
++ ) { cin
>> res
[ i
] . first
>> res
[ i
] . second
; } sort ( res
. begin ( ) , res
. end ( ) , compare
) ; int freetime
= 0 ; int busytime
= res
[ 0 ] . second
- res
[ 0 ] . first
; for ( int i
= 1 ; i
< a
; i
++ ) { if ( res
[ i
] . first
<= res
[ i
- 1 ] . second
) { res
[ i
] . first
= res
[ i
- 1 ] . first
; res
[ i
] . second
= max ( res
[ i
- 1 ] . second
, res
[ i
] . second
) ; } else { freetime
= max ( freetime
, res
[ i
] . first
- res
[ i
- 1 ] . second
) ; } busytime
= max ( busytime
, res
[ i
] . second
- res
[ i
] . first
) ; } cout
<< busytime
<< " " << freetime
<< endl
; return 0 ;
}
總結
以上是生活随笔 為你收集整理的算法设计与分析-实验2 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。