生活随笔
收集整理的這篇文章主要介紹了
东北大学第二场算法题解报告
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
7-1 N個數求和
題解 按照小學學的分數,將輸入的分數全部通分,然后分子分母求最大公約數化簡 由題目知分數輸入的時候均以 分子/分母 給出,我們可以利用 scanf 中的格式符進行輸入 代碼
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std
;
long long gcd ( long long x
, long long y
)
{
if ( y
< 0 ) return gcd ( x
, - y
) ;
if ( ! y
) return x
;
else return gcd ( y
, x
% y
) ;
}
struct FS
{
long long Fz
, Fm
;
} a
[ 105 ] ;
long long FFm
= 1 , FFz
= 0 ;
int main ( )
{
int n
;
scanf ( "%d" , & n
) ;
for ( int i
= 1 ; i
<= n
; ++ i
) scanf ( "%lld/%lld" , & a
[ i
] . Fz
, & a
[ i
] . Fm
) ;
for ( int i
= 1 ; i
<= n
; ++ i
)
{
long long k
= gcd ( FFm
, a
[ i
] . Fm
) ;
FFm
= FFm
/ k
* a
[ i
] . Fm
;
}
for ( int i
= 1 ; i
<= n
; ++ i
) FFz
+ = FFm
/ a
[ i
] . Fm
* a
[ i
] . Fz
;
if ( ! FFz
)
{
printf ( "0" ) ;
return 0 ;
}
long long ZZZ
= gcd ( FFm
, FFz
) ;
FFm
/ = ZZZ
;
FFz
/ = ZZZ
;
if ( FFz
* FFz
< FFm
* FFm
)
{
printf ( "%lld/%lld" , FFz
, FFm
) ;
return 0 ;
}
long long A
, B
;
B
= FFz
% FFm
;
A
= FFz
/ FFm
;
printf ( "%lld" , A
) ;
if ( B
) printf ( " %lld/%lld" , B
, FFm
) ;
return 0 ;
}
7-2 比較大小
題解 我這怎么寫題解…… 可以使用C艸的algorithm里面的sort搞個排序真實大材小用 也可以手寫冒泡真實大材小用*2 也可以分類討論 或者搞個二叉搜索樹啥的(x) 代碼
7-3 A-B
題解 讀入兩個字符串,同時申請一個大小為128的布爾(bool)型數組 (可見的ASCII碼和空白字符在ascii碼表上占據32~126) 先讀入兩個字符串,并單獨掃一遍B字符串,B字符串出現過的字符在之前申請的bool型數組上做標記 再逐個字符檢查A字符串,當檢查的字符沒在布爾型數組上做過標記的時候才輸出 代碼
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std
;
int a
[ 3 ] ;
int main ( )
{
scanf ( "%d%d%d" , & a
[ 0 ] , & a
[ 1 ] , & a
[ 2 ] ) ;
sort ( a
, a
+ 3 ) ;
printf ( "%d->%d->%d" , a
[ 0 ] , a
[ 1 ] , a
[ 2 ] ) ;
return 0 ;
}
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std
;
char A
[ 10005 ] ;
char B
[ 10005 ] ;
bool N
[ 128 ] ;
##
7 - 4 計算指數
題解
n不超過
10 ,直接暴力循環可得也不會TLE
(但建議學習一下快速冪算法,代碼中使用的即為快速冪算法)
代碼
int main ( )
{
for ( int i
= 0 ; ; ++ i
)
{
A
[ i
] = getchar ( ) ;
if ( A
[ i
] == '\n' ) break ;
}
for ( int i
= 0 ; ; ++ i
)
{
B
[ i
] = getchar ( ) ;
if ( B
[ i
] == '\n' ) break ;
}
for ( int i
= 0 ; B
[ i
] != '\n' ; ++ i
) N
[ ( int ) B
[ i
] ] = true
;
for ( int i
= 0 ; A
[ i
] != '\n' ; ++ i
)
{
if ( ! N
[ A
[ i
] ] ) printf ( "%c" , A
[ i
] ) ;
}
return 0 ;
}
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std
;
int Pow4 ( int a
, int b
)
{
int r
= 1 ;
while ( b
)
{
if ( b
& 1 ) r
* = a
;
a
* = a
;
b
>>= 1 ;
}
return r
;
}
int main ( )
{
int n
;
scanf ( "%d" , & n
) ;
printf ( "2^%d = %d" , n
, Pow4 ( 2 , n
) ) ;
return 0 ;
}
7-5 計算階乘和
題解 直接循環暴力求解即可 代碼
7-6 簡單題
題解 此題+巖漿=黑曜石 直接輸出即可 代碼
7-7 跟奧巴馬一起畫方塊
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std
;
int main ( )
{
int n
, t
= 1 , S
= 0 ;
scanf ( "%d" , & n
) ;
for ( int i
= 1 ; i
<= n
; ++ i
)
{
t
* = i
;
S
+ = t
;
}
printf ( "%d" , S
) ;
return 0 ;
}
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std
;
int main ( )
{
printf ( "This is a simple problem." ) ;
return 0 ;
}
題解 我咋感覺這個題之前在學校做過 按照題目要求循環就好了 代碼
7-8 查驗身份證
題解 按照題目要求直接做就好了 (別忘了申請兩個常數數組把加的權和對應的碼放進去) 代碼
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std
;
char a
;
int main ( )
{
int n
, x
;
scanf ( "%d %c" , & n
, & a
) ;
x
= ( n
+ 1 ) / 2 ;
for ( int i
= 1 ; i
<= x
; ++ i
)
{
for ( int j
= 1 ; j
<= n
; ++ j
)
{
printf ( "%c" , a
) ;
}
printf ( "\n" ) ;
}
return 0 ;
}
7-9 集合相似度
題解 其實也是個按照題面做就行的題,不過群里有人說超時,我在這說點解決方法 輸入結束后將每個集合內的數據從小到大排序(推薦學習一下快速排序,C艸用戶可直接使用STL內的 sort) 然后將集合內重復數據去除(可以暴力做,C艸用戶可直接使用STL內的unique) 這樣每個集合的大小都是已知的 排序的用途:找相同數據數目的時候,可以先定義兩個變量i,j。 分別指代兩個數組(下文分別稱之為A,B)的下標(i,j別忘記初始化) 然后如果A[i]>B[j],我們只需要將j+=1; 同理,如果A[i]<B[j] ,我們只需要將i+=1。 A[i]==B[j]時,我們計數+=1(即Nc+=1)同時i+=1, j+=1 當任意一個下標掃完整個數組后停止尋找 (因為此時每個數組內的數據是由小到大排序的且無重復數據,若A[i]>B[j] ,那么B數組內有可能等于 A[i]的數據只可能在B[j]之后,若B數組檢查完畢,則A當前數字以及之后的數組均不存在與B數組中,反 過來也是同理,不再贅述) 此時計算Nc所需時間為O(min(A數組元素數目,B數組元素數目))
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std
;
const char ST
[ 11 ] = { '1' , '0' , 'X' , '9' , '8' , '7' , '6' , '5' , '4' , '3' , '2' } ;
const int St
[ 17 ] = { 7 , 9 , 10 , 5 , 8 , 4 , 2 , 1 , 6 , 3 , 7 , 9 , 10 , 5 , 8 , 4 , 2 } ;
char A
[ 20 ] ;
int main ( )
{
int n
;
bool OK
= true
;
scanf ( "%d" , & n
) ;
for ( int i
= 1 ; i
<= n
; ++ i
)
{
scanf ( "%s" , A
) ;
int Tem
= 0 ;
bool OK2
= true
;
for ( int j
= 0 ; j
< 17 ; ++ j
)
{
if ( A
[ j
] >= '0' && A
[ j
] <= '9' )
{
Tem
+ = ( A
[ j
] - '0' ) * St
[ j
] ;
}
else
{
OK2
= false
;
break ;
}
}
Tem
% = 11 ;
if ( ! OK2
|| ST
[ Tem
] != A
[ 17 ] )
{
printf ( "%s\n" , A
) ;
OK
= false
;
continue ;
}
}
if ( OK
) printf ( "All passed" ) ;
return 0 ;
}
Nt=兩個數組元素數目之和-Nc 代碼
7-10 樹的遍歷
解題必備知識 二叉樹的定義,二叉樹先序、中序、后序和層序遍歷的定義與性質
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std
;
int a
[ 51 ] [ 10005 ] ;
int main ( )
{
int N
, K
;
scanf ( "%d" , & N
) ;
for ( int i
= 1 ; i
<= N
; ++ i
)
{
int M
;
scanf ( "%d" , & M
) ;
for ( int j
= 1 ; j
<= M
; ++ j
)
{
scanf ( "%d" , & a
[ i
] [ j
] ) ;
}
sort ( a
[ i
] + 1 , a
[ i
] + M
+ 1 ) ;
a
[ i
] [ 0 ] = unique ( a
[ i
] + 1 , a
[ i
] + M
+ 1 ) - & a
[ i
] [ 1 ] ;
}
scanf ( "%d" , & K
) ;
while ( K
-- )
{
int ta
, tb
;
scanf ( "%d%d" , & ta
, & tb
) ;
int Nc
= 0 , Nt
= a
[ ta
] [ 0 ] + a
[ tb
] [ 0 ] ;
for ( int i
= 1 , j
= 1 ; i
<= a
[ ta
] [ 0 ] && j
<= a
[ tb
] [ 0 ] ; )
{
if ( a
[ ta
] [ i
] == a
[ tb
] [ j
] )
{
Nc
++ ;
i
++ ;
j
++ ;
continue ;
}
if ( a
[ ta
] [ i
] > a
[ tb
] [ j
] ) j
++ ;
else i
++ ;
}
Nt
- = Nc
;
double ans
= ( ( double ) Nc
) / ( ( double ) Nt
) * 100 ;
printf ( "%.2lf%%\n" , ans
) ;
}
return 0 ;
}
(推薦的網址: https://blog.csdn.net/qq_42475914/article/details/84311235 ) 題解 二叉樹前序遍歷是先輸出當前遍歷節點,再按照左子樹右子樹順序遍歷 二叉樹中序遍歷是先遍歷左子樹,再輸出當前遍歷節點,再遍歷右子樹 二叉樹后序遍歷是先按照左子樹右子樹順序遍歷,再輸出當前遍歷節點 二叉樹層序遍歷是按照二叉樹的深度從左往右進行輸出 于是我們可知,后序遍歷序列的最后一個數字是根節點 我們就可以對照中序遍歷序列找出其左右子樹長度,按照長度再后序遍歷序列中找出其子樹的后序遍歷即可。 代碼
#include <iostream>
#include <cstdio>
using namespace std
;
int H
[ 35 ] , Z
[ 35 ] ;
int ans
[ 35 ] [ 35 ] ;
void dfs ( int H_l
, int H_r
, int Z_l
, int Z_r
, int cnt
)
{
ans
[ cnt
] [ 0 ] ++ ;
ans
[ cnt
] [ ans
[ cnt
] [ 0 ] ] = H
[ H_r
] ;
for ( int i
= Z_l
; i
<= Z_r
; ++ i
)
{
if ( Z
[ i
] == H
[ H_r
] )
{
if ( i
- 1 >= Z_l
) dfs ( H_l
, H_l
+ i
- Z_l
- 1 , Z_l
, i
- 1 , cnt
+ 1 ) ;
if ( i
+ 1 <= Z_r
) dfs ( H_l
+ i
- Z_l
, H_r
- 1 , i
+ 1 , Z_r
, cnt
+ 1 ) ;
}
}
return ;
}
int main ( )
{
int N
;
scanf ( "%d" , & N
) ;
for ( int i
= 1 ; i
<= N
; ++ i
) scanf ( "%d" , & H
[ i
] ) ;
for ( int i
= 1 ; i
<= N
; ++ i
) scanf ( "%d" , & Z
[ i
] ) ;
dfs ( 1 , N
, 1 , N
, 1 ) ;
for ( int i
= 1 ; ans
[ i
] [ 0 ] != 0 ; ++ i
)
{
for ( int j
= 1 ; j
<= ans
[ i
] [ 0 ] ; ++ j
)
{
printf ( "%d" , ans
[ i
] [ j
] ) ;
if ( j
!= ans
[ i
] [ 0 ] || ans
[ i
+ 1 ] [ 0 ] != 0 ) printf ( " " ) ;
}
}
return 0 ;
}
7-11 家庭房產
題解 使用并查集算法將不同人的信息進行合并,最后輸出信息即可 并查集 在計算機科學中,并查集是一種樹型的數據結構,用于處理一些不交集(Disjoint Sets)的合并及查詢 問題。 有一個聯合查找算法(union-find algorithm)定義了兩個用于此數據結構的操作: ·Find:確定元素屬于哪一個子集。這個確定方法就是不斷向上查找找到它的根節點,它可以被用來確 定兩個元素是否屬于同一子集。 ·Union:將兩個子集合并成同一個集合。 (定義來自網絡,其實還有一個judge操作) 代碼
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std
;
struct PEO
{
int id
;
int num_house
, num_family
, num_S
;
double PJ_house ( ) const
{
return ( ( double ) num_house
) / ( ( double ) num_family
) ;
}
double PJ_S ( ) const
{
return ( ( double ) num_S
) / ( ( double ) num_family
) ;
}
bool operator
< ( const PEO
& b
) const
{
if ( PJ_S ( ) != b
. PJ_S ( ) ) return PJ_S ( ) > b
. PJ_S ( ) ;
else return id
< b
. id
;
}
} A
[ 10000 ] ;
int Find ( int x
)
{
if ( A
[ x
] . id
!= x
) A
[ x
] . id
= Find ( A
[ x
] . id
) ;
return A
[ x
] . id
;
}
void unioon ( int x
, int y
)
{
x
= Find ( x
) ;
y
= Find ( y
) ;
if ( x
== y
) return ;
if ( x
> y
) swap ( x
, y
) ;
A
[ y
] . id
= x
;
A
[ x
] . num_family
+ = A
[ y
] . num_family
;
A
[ x
] . num_house
+ = A
[ y
] . num_house
;
A
[ x
] . num_S
+ = A
[ y
] . num_S
;
A
[ y
] . num_S
= - 1 ;
}
7-12 最長對稱子串
int main ( )
{
int N
;
scanf ( "%d" , & N
) ;
for ( int i
= 0 ; i
<= 9999 ; ++ i
)
{
A
[ i
] . id
= i
;
A
[ i
] . num_family
= 1 ;
A
[ i
] . num_house
= 0 ;
A
[ i
] . num_S
= 0 ;
}
for ( int i
= 1 ; i
<= N
; ++ i
)
{
scanf ( "%d%d%d%d" , & CZ
[ i
] [ 1 ] , & CZ
[ i
] [ 2 ] , & CZ
[ i
] [ 3 ] , & CZ
[ i
] [ 4 ] ) ;
vis
[ CZ
[ i
] [ 1 ] ] = true
;
if ( CZ
[ i
] [ 2 ] != - 1 ) vis
[ CZ
[ i
] [ 2 ] ] = true
;
if ( CZ
[ i
] [ 3 ] != - 1 ) vis
[ CZ
[ i
] [ 3 ] ] = true
;
for ( int j
= 1 ; j
<= CZ
[ i
] [ 4 ] ; ++ j
)
{
scanf ( "%d" , & CZ
[ i
] [ 4 + j
] ) ;
vis
[ CZ
[ i
] [ 4 + j
] ] = true
;
}
scanf ( "%d%d" , & A
[ CZ
[ i
] [ 1 ] ] . num_house
, & A
[ CZ
[ i
] [ 1 ] ] . num_S
) ;
}
for ( int i
= 1 ; i
<= N
; ++ i
)
{
if ( CZ
[ i
] [ 2 ] != - 1 ) unioon ( CZ
[ i
] [ 1 ] , CZ
[ i
] [ 2 ] ) ;
if ( CZ
[ i
] [ 3 ] != - 1 ) unioon ( CZ
[ i
] [ 1 ] , CZ
[ i
] [ 3 ] ) ;
for ( int j
= 1 ; j
<= CZ
[ i
] [ 4 ] ; ++ j
)
{
unioon ( CZ
[ i
] [ 1 ] , CZ
[ i
] [ 4 + j
] ) ;
}
}
sort ( A
, A
+ 10000 ) ;
int cnt
= 0 ;
while ( vis
[ A
[ cnt
] . id
] ) cnt
++ ;
printf ( "%d\n" , cnt
) ;
for ( int i
= 0 ; i
< cnt
; ++ i
)
{
printf ( "
% 04 d
% d
% .3lf
% .3lf \n"
, A
[ i
] . id
, A
[ i
] . num_family
, A
[ i
] . PJ_house ( ) , A
[ i
] . PJ_S ( ) ) ;
}
return 0 ;
}
題解 1.馬拉車算法(Manacher‘s Algorithm),時間復雜度為O(N) 2.本題解中代碼:使用動態規劃,時間復雜度為O(N^2) 定義:s[i,j]是字符串s由下標i到下標j的字符組成的字符串 dp[i,j]判斷s[i,j]是否是回文串 易知, dp[i,j]=true的條件是dp[i+1,j-1]=true且s[i]==s[j] 然后跑一個二重循環,遞推就可以了,每個回文串的長度則是j-i+1 代碼
7-13 腫瘤診斷
題解 使用BFS求出每一個腫瘤的體積,再判斷是否超過閾值即可 不要使用dfs,會出現堆棧溢出的情況 代碼
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std
;
char A
[ 1005 ] ;
bool t
[ 1005 ] [ 1005 ] ;
int main ( )
{
int ans
= 1 ;
int len
= 1 ;
while ( ( A
[ len
] = getchar ( ) ) != EOF ) len
++ ;
for ( int i
= 1 ; i
<= len
; ++ i
) t
[ i
] [ 1 ] = true
;
for ( int i
= 1 ; i
< len
; ++ i
) if ( A
[ i
] == A
[ i
+ 1 ] ) t
[ i
] [ 2 ] = true
;
for ( int i
= 3 ; i
<= len
; ++ i
)
{
for ( int j
= 1 ; j
+ i
- 1 <= len
; ++ j
)
{
if ( t
[ j
+ 1 ] [ i
- 2 ] && A
[ j
] == A
[ j
+ i
- 1 ] )
{
t
[ j
] [ i
] = true
;
ans
= i
;
}
else t
[ j
] [ i
] = false
;
}
}
printf ( "%d" , ans
) ;
return 0 ;
} #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std
;
bool vis
[ 1287 ] [ 129 ] [ 61 ] ;
bool mpa
[ 1287 ] [ 129 ] [ 61 ] ;
const int xx
[ 6 ] = { 1 , - 1 , 0 , 0 , 0 , 0 } ;
const int yy
[ 6 ] = { 0 , 0 , 1 , - 1 , 0 , 0 } ;
const int zz
[ 6 ] = { 0 , 0 , 0 , 0 , 1 , - 1 } ;
int M
, N
, L
, T
;
struct point
{
int x
, y
, z
;
} ;
int dfs ( int x
, int y
, int z
)
{
int res
= 0 ;
vis
[ x
] [ y
] [ z
] = true
;
point st
;
st
. x
= x
;
st
. y
= y
;
st
. z
= z
;
queue
< point
> q1
;
q1
. push ( st
) ;
while ( ! q1
. empty ( ) )
{
point w
= q1
. front ( ) ;
q1
. pop ( ) ;
if ( ! mpa
[ w
. x
] [ w
. y
] [ w
. z
] ) continue ;
res
++ ;
for ( int i
= 0 ; i
< 6 ; ++ i
)
{
point tem
= w
;
tem
. x
+ = xx
[ i
] ;
tem
. y
+ = yy
[ i
] ;
tem
. z
+ = zz
[ i
] ;
if ( tem
. x
>= 1 && tem
. x
<= M
&& tem
. y
>= 1 && tem
. y
<= N
&& tem
. z
>= 1 && tem
. z
<= L
&& ! vis
[ tem
. x
]
[ tem
. y
] [ tem
. z
] )
{
q1
. push ( tem
) ;
vis
[ tem
. x
] [ tem
. y
] [ tem
. z
] = true
;
}
}
}
return res
;
}
int main ( )
{
scanf ( "%d%d%d%d" , & M
, & N
, & L
, & T
) ;
for ( int k
= 1 ; k
<= L
; ++ k
)
{
for ( int i
= 1 ; i
<= M
; ++ i
)
{
for ( int j
= 1 ; j
<= N
; ++ j
)
{
int t
;
scanf ( "%d" , & t
) ;
if ( t
) mpa
[ i
] [ j
] [ k
] = true
;
else mpa
[ i
] [ j
] [ k
] = false
;
}
}
}
int ans
= 0 ;
for ( int k
= 1 ; k
<= L
; ++ k
)
{
for ( int i
= 1 ; i
<= M
; ++ i
)
{
for ( int j
= 1 ; j
<= N
; ++ j
)
{
if ( vis
[ i
] [ j
] [ k
] ) continue ;
int tem
= dfs ( i
, j
, k
) ;
if ( tem
>= T
) ans
+ = tem
;
}
}
}
printf ( "%d" , ans
) ;
return 0 ;
}
7-14 垃圾箱分布
題解 Gx表示的垃圾桶編號可以看做1000+x的節點(技巧) 這個題需要使用最短路算法,請自行百度 (推薦的網站:https://blog.csdn.net/strve/article/details/80957491) ①所以垃圾箱的位置必須選在到所有居民點的最短距離最長的地方 ②如果解不唯一,則輸出到所有居民點的平均距離最短的那個解 ③如果這樣的解還是不唯一,則輸出編號最小的地點。 三句話決定排序關鍵字: 到居民樓最短距離最長的路徑長度(降序) 總路徑長度(升序) 編號(升序) 則序列的第一個符合到居民樓最短距離最長的路徑長度< Ds的即為答案 代碼
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std
;
struct Edge
{
int n
, v
;
long long w
;
} edge
[ 20005 ] ;
int head
[ 1050 ] , num_edge
;
void add_edge ( int u
, int v
, long long w
)
{
num_edge
++ ;
edge
[ num_edge
] . n
= head
[ u
] ;
edge
[ num_edge
] . v
= v
;
edge
[ num_edge
] . w
= w
;
head
[ u
] = num_edge
;
}
long long dis
[ 1050 ] ;
bool vis
[ 1050 ] ;
long long ans
[ 15 ] [ 3 ] ;
int N
, M
, K
;
long long D
;
void SPFA ( int u
)
{
memset ( dis
, 0x3f , sizeof ( dis
) ) ;
memset ( vis
, 0 , sizeof ( vis
) ) ;
queue
< int > q1
;
q1
. push ( u
) ;
vis
[ u
] = true
;
dis
[ u
] = 0 ;
while ( ! q1
. empty ( ) )
{
int w
= q1
. front ( ) ;
q1
. pop ( ) ;
vis
[ w
] = false
;
for ( int i
= head
[ w
] ; i
; i
= edge
[ i
] . n
)
{
if ( dis
[ edge
[ i
] . v
] > dis
[ w
] + edge
[ i
] . w
)
{
dis
[ edge
[ i
] . v
] = dis
[ w
] + edge
[ i
] . w
;
if ( ! vis
[ edge
[ i
] . v
] )
{
vis
[ edge
[ i
] . v
] = true
;
q1
. push ( edge
[ i
] . v
) ;
}
}
}
}
for ( int i
= 1 ; i
<= N
; ++ i
)
{
if ( dis
[ i
] > ans
[ u
- 1000 ] [ 0 ] ) ans
[ u
- 1000 ] [ 0 ] = dis
[ i
] ;
ans
[ u
- 1000 ] [ 2 ] + = dis
[ i
] ;
}
ans
[ u
- 1000 ] [ 1 ] = 9223372036854775807LL ;
for ( int i
= 1 ; i
<= N
; ++ i
)
{
if ( dis
[ i
] < ans
[ u
- 1000 ] [ 1 ] ) ans
[ u
- 1000 ] [ 1 ] = dis
[ i
] ;
}
return ;
}
int main ( )
{
scanf ( "%d%d%d%lld" , & N
, & M
, & K
, & D
) ;
for ( int i
= 1 ; i
<= K
; ++ i
)
{
char A
[ 10 ] = { 0 } , B
[ 10 ] = { 0 } ;
int a
= 0 , b
= 0 ;
long long w
;
bool a_g
= false
, b_g
= false
;
scanf ( "%s%s%lld" , A
, B
, & w
) ;
int len
= strlen ( A
) ;
for ( int j
= 0 ; j
< len
; ++ j
)
{
if ( A
[ j
] == 'G' ) a_g
= true
;
else
{
a
* = 10 ;
a
+ = A
[ j
] - '0' ;
}
}
len
= strlen ( B
) ;
for ( int j
= 0 ; j
< len
; ++ j
)
{
if ( B
[ j
] == 'G' ) b_g
= true
;
else
{
b
* = 10 ;
b
+ = B
[ j
] - '0' ;
}
}
if ( a_g
) a
+ = 1000 ;
if ( b_g
) b
+ = 1000 ;
add_edge ( a
, b
, w
) ;
add_edge ( b
, a
, w
) ;
}
for ( int i
= 1 ; i
<= M
; ++ i
)
{
SPFA ( 1000 + i
) ;
}
int ppd
= - 1 ;
for ( int i
= 1 ; i
<= M
; ++ i
)
{
if ( ans
[ i
] [ 0 ] > D
) continue ;
if ( ppd
== - 1 )
{
ppd
= i
;
continue ;
}
if ( ans
[ i
] [ 1 ] > ans
[ ppd
] [ 1 ] ) ppd
= i
;
else if ( ans
[ i
] [ 1 ] == ans
[ ppd
] [ 1 ] && ans
[ i
] [ 2 ] < ans
[ ppd
] [ 2 ] )
{
ppd
= i
;
}
}
if ( ppd
== - 1 )
{
printf ( "No Solution" ) ;
}
else
{
printf ( "G%d\n" , ppd
) ;
printf ( "%.1lf %.1lf" , ( double ) ans
[ ppd
] [ 1 ] , ( ( double ) ans
[ ppd
]
[ 2 ] / ( double ) N
) ) ;
}
return 0 ;
}
7-15 迎風一刀斬
題解 簡單十分復雜的分類討論 1.看輸入的兩個多邊形端點數之和是否超過8或者是否有任意一個超過5,有則輸出NO 2.看多邊形與坐標軸平行的邊數是否為端點數-1,如果不等于,看是否為兩個矩形,若是兩個矩形,再 看這兩個矩形是否有邊長相等;有則輸出YES,除此之外邊數不等于端點數-1的情況均輸出NO 3.看多邊形是否為凸多邊形(可以凸包,也可以強行討論(不同討論方式情況不同,某種方式討論出十 二種情況每種還巨麻煩)(自認為最優解是看多邊形的非直角,五邊形的需要2個鈍角,四邊形需要1鈍 1銳,通過向量求cos即可)不是則輸出NO) 4.如果兩塊殘片都是有1條斜邊的四邊形,除了要檢查兩條斜邊是否一致,還要檢查兩塊殘片內部的銳 角是否相等,如下圖。 5.計算斜邊斜率以及斜邊長度,如果長度相等,且斜邊平行/垂直或水平翻轉的其中一條斜邊與另一條平 行/垂直即為YES,否則為NO 這個題需要使用最短路算法,請自行百度 (推薦的網站:https://blog.csdn.net/strve/article/details/80957491) ①所以垃圾箱的位置必須選在到所有居民點的最短距離最長的地方 ②如果解不唯一,則輸出到所有居民點的平均距離最短的那個解 ③如果這樣的解還是不唯一,則輸出編號最小的地點。
三句話決定排序關鍵字: 到居民樓最短距離最長的路徑長度(降序) 總路徑長度(升序) 編號(升序) 【則序列的第一個符合到居民樓最短距離最長的路徑長度< Ds的即為答案】 (然后按照題目要求篩去不符合要求的答案即可) 代碼
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std
;
int main ( )
{
int N
;
scanf ( "%d" , & N
) ;
while ( N
-- )
{
int a
, b
;
int A
[ 15 ] [ 2 ] = { 0 } , B
[ 15 ] [ 2 ] = { 0 } ;
scanf ( "%d" , & a
) ;
for ( int i
= 1 ; i
<= a
; ++ i
) scanf ( "%d%d" , & A
[ i
] [ 0 ] , & A
[ i
] [ 1 ] ) ;
A
[ a
+ 1 ] [ 0 ] = A
[ 1 ] [ 0 ] ;
A
[ a
+ 1 ] [ 1 ] = A
[ 1 ] [ 1 ] ;
scanf ( "%d" , & b
) ;
for ( int i
= 1 ; i
<= b
; ++ i
) scanf ( "%d%d" , & B
[ i
] [ 0 ] , & B
[ i
] [ 1 ] ) ;
B
[ b
+ 1 ] [ 0 ] = B
[ 1 ] [ 0 ] ;
B
[ b
+ 1 ] [ 1 ] = B
[ 1 ] [ 1 ] ;
if ( a
> 5 || b
> 5 || a
+ b
> 8 )
{
printf ( "NO\n" ) ;
continue ;
}
int xa_id
= 0 , xb_id
= 0 ;
int cnta
= 0 , cntb
= 0 ;
for ( int i
= 1 ; i
<= a
; ++ i
)
{
if ( A
[ i
] [ 0 ] == A
[ i
+ 1 ] [ 0 ] || A
[ i
] [ 1 ] == A
[ i
+ 1 ] [ 1 ] ) cnta
++ ;
else xa_id
= i
;
}
for ( int i
= 1 ; i
<= b
; ++ i
)
{
if ( B
[ i
] [ 0 ] == B
[ i
+ 1 ] [ 0 ] || B
[ i
] [ 1 ] == B
[ i
+ 1 ] [ 1 ] ) cntb
++ ;
else xb_id
= i
;
}
if ( cnta
!= a
- 1 || cntb
!= b
- 1 )
{
if ( cnta
== 4 && cntb
== 4 && a
== 4 && b
== 4 )
{
int len
[ 3 ] ;
len
[ 0 ] = max ( A
[ 1 ] [ 0 ] > A
[ 2 ] [ 0 ] ? A
[ 1 ] [ 0 ] - A
[ 2 ] [ 0 ] : A
[ 2 ] [ 0 ] - A
[ 1 ] [ 0 ] , A
[ 1 ]
[ 1 ] > A
[ 2 ] [ 1 ] ? A
[ 1 ] [ 1 ] - A
[ 2 ] [ 1 ] : A
[ 2 ] [ 1 ] - A
[ 1 ] [ 1 ] ) ;
len
[ 1 ] = max ( A
[ 2 ] [ 0 ] > A
[ 3 ] [ 0 ] ? A
[ 2 ] [ 0 ] - A
[ 3 ] [ 0 ] : A
[ 3 ] [ 0 ] - A
[ 2 ] [ 0 ] , A
[ 2 ]
[ 1 ] > A
[ 3 ] [ 1 ] ? A
[ 2 ] [ 1 ] - A
[ 3 ] [ 1 ] : A
[ 3 ] [ 1 ] - A
[ 2 ] [ 1 ] ) ;
len
[ 2 ] = max ( B
[ 1 ] [ 0 ] > B
[ 2 ] [ 0 ] ? B
[ 1 ] [ 0 ] - B
[ 2 ] [ 0 ] : B
[ 2 ] [ 0 ] - B
[ 1 ] [ 0 ] , B
[ 1 ]
[ 1 ] > B
[ 2 ] [ 1 ] ? B
[ 1 ] [ 1 ] - B
[ 2 ] [ 1 ] : B
[ 2 ] [ 1 ] - B
[ 1 ] [ 1 ] ) ;
if ( len
[ 0 ] == len
[ 2 ] || len
[ 1 ] == len
[ 2 ] )
{
printf ( "YES\n" ) ;
continue ;
}
}
printf ( "NO\n" ) ;
continue ;
}
if ( a
== 5 )
{
long long xa
, xb
, ya
, yb
, xc
, xd
, yc
, yd
;
int t1
= xa_id
, t2
= ( xa_id
) % a
+ 1 ;
xa
= A
[ t1
] [ 0 ] - A
[ t1
+ 1 ] [ 0 ] ;
xb
= A
[ t1
] [ 0 ] - A
[ ( t1
+ 3 ) % a
+ 1 ] [ 0 ] ;
ya
= A
[ t1
] [ 1 ] - A
[ t1
+ 1 ] [ 1 ] ;
yb
= A
[ t1
] [ 1 ] - A
[ ( t1
+ 3 ) % a
+ 1 ] [ 1 ] ;
xc
= A
[ t2
] [ 0 ] - A
[ t2
+ 1 ] [ 0 ] ;
xd
= A
[ t2
] [ 0 ] - A
[ ( t2
+ 3 ) % a
+ 1 ] [ 0 ] ;
yc
= A
[ t2
] [ 1 ] - A
[ t2
+ 1 ] [ 1 ] ;
yd
= A
[ t2
] [ 1 ] - A
[ ( t2
+ 3 ) % a
+ 1 ] [ 1 ] ;
if ( xa
* xb
+ ya
* yb
>= 0 || xc
* xd
+ yc
* yd
>= 0 )
{
printf ( "NO\n" ) ;
continue ;
}
}
if ( b
== 5 )
{
long long xa
, xb
, ya
, yb
, xc
, xd
, yc
, yd
;
int t1
= xb_id
, t2
= ( xb_id
) % b
+ 1 ;
xa
= B
[ t1
] [ 0 ] - B
[ t1
+ 1 ] [ 0 ] ;
xb
= B
[ t1
] [ 0 ] - B
[ ( t1
+ 3 ) % b
+ 1 ] [ 0 ] ;
ya
= B
[ t1
] [ 1 ] - B
[ t1
+ 1 ] [ 1 ] ;
yb
= B
[ t1
] [ 1 ] - B
[ ( t1
+ 3 ) % b
+ 1 ] [ 1 ] ;
xc
= B
[ t2
] [ 0 ] - B
[ t2
+ 1 ] [ 0 ] ;
xd
= B
[ t2
] [ 0 ] - B
[ ( t2
+ 3 ) % b
+ 1 ] [ 0 ] ;
yc
= B
[ t2
] [ 1 ] - B
[ t2
+ 1 ] [ 1 ] ;
yd
= B
[ t2
] [ 1 ] - B
[ ( t2
+ 3 ) % b
+ 1 ] [ 1 ] ;
if ( xa
* xb
+ ya
* yb
>= 0 || xc
* xd
+ yc
* yd
>= 0 )
{
printf ( "NO\n" ) ;
continue ;
}
}
if ( a
== 4 )
{
long long xa
, xb
, ya
, yb
, xc
, xd
, yc
, yd
;
int t1
= xa_id
, t2
= ( xa_id
) % a
+ 1 ;
xa
= A
[ t1
] [ 0 ] - A
[ t1
+ 1 ] [ 0 ] ;
xb
= A
[ t1
] [ 0 ] - A
[ ( t1
+ 2 ) % a
+ 1 ] [ 0 ] ;
ya
= A
[ t1
] [ 1 ] - A
[ t1
+ 1 ] [ 1 ] ;
yb
= A
[ t1
] [ 1 ] - A
[ ( t1
+ 2 ) % a
+ 1 ] [ 1 ] ;
xc
= A
[ t2
] [ 0 ] - A
[ t2
+ 1 ] [ 0 ] ;
xd
= A
[ t2
] [ 0 ] - A
[ ( t2
+ 2 ) % a
+ 1 ] [ 0 ] ;
yc
= A
[ t2
] [ 1 ] - A
[ t2
+ 1 ] [ 1 ] ;
yd
= A
[ t2
] [ 1 ] - A
[ ( t2
+ 2 ) % a
+ 1 ] [ 1 ] ;
if ( ( xa
* xb
+ ya
* yb
>= 0 && xc
* xd
+ yc
* yd
>= 0 ) || ( xa
* xb
+ ya
* yb
< 0 && xc
* xd
+ yc
* yd
< 0 ) )
{
printf ( "NO\n" ) ;
continue ;
}
}
if ( b
== 4 )
{
long long xa
, xb
, ya
, yb
, xc
, xd
, yc
, yd
;
int t1
= xb_id
, t2
= ( xb_id
) % b
+ 1 ;
xa
= B
[ t1
] [ 0 ] - B
[ t1
+ 1 ] [ 0 ] ;
xb
= B
[ t1
] [ 0 ] - B
[ ( t1
+ 2 ) % b
+ 1 ] [ 0 ] ;
ya
= B
[ t1
] [ 1 ] - B
[ t1
+ 1 ] [ 1 ] ;
yb
= B
[ t1
] [ 1 ] - B
[ ( t1
+ 2 ) % b
+ 1 ] [ 1 ] ;
xc
= B
[ t2
] [ 0 ] - B
[ t2
+ 1 ] [ 0 ] ;
xd
= B
[ t2
] [ 0 ] - B
[ ( t2
+ 2 ) % b
+ 1 ] [ 0 ] ;
yc
= B
[ t2
] [ 1 ] - B
[ t2
+ 1 ] [ 1 ] ;
yd
= B
[ t2
] [ 1 ] - B
[ ( t2
+ 2 ) % b
+ 1 ] [ 1 ] ;
if ( ( xa
* xb
+ ya
* yb
>= 0 && xc
* xd
+ yc
* yd
>= 0 ) || ( xa
* xb
+ ya
* yb
< 0 && xc
* xd
+ yc
* yd
< 0 ) )
{
printf ( "NO\n" ) ;
continue ;
}
}
long long len
[ 7 ] ;
len
[ 1 ] = ( long long ) ( A
[ xa_id
] [ 0 ] - A
[ xa_id
+ 1 ] [ 0 ] ) ;
len
[ 2 ] = ( long long ) ( A
[ xa_id
] [ 1 ] - A
[ xa_id
+ 1 ] [ 1 ] ) ;
len
[ 3 ] = len
[ 1 ] * len
[ 1 ] + len
[ 2 ] * len
[ 2 ] ;
len
[ 4 ] = ( long long ) ( B
[ xb_id
] [ 0 ] - B
[ xb_id
+ 1 ] [ 0 ] ) ;
len
[ 5 ] = ( long long ) ( B
[ xb_id
] [ 1 ] - B
[ xb_id
+ 1 ] [ 1 ] ) ;
len
[ 6 ] = len
[ 4 ] * len
[ 4 ] + len
[ 5 ] * len
[ 5 ] ;
if ( len
[ 3 ] == len
[ 6 ] &&
( len
[ 1 ] * len
[ 5 ] == len
[ 2 ] * len
[ 4 ] || len
[ 2 ] * len
[ 5 ] == len
[ 1 ] * len
[ 4 ] || len
[ 1 ] * len
[ 4 ] + len
[ 2
] * len
[ 5 ] == 0 || len
[ 2 ] * len
[ 4 ] + len
[ 1 ] * len
[ 5 ] == 0 ) )
{
if ( a
== 4 && b
== 4 )
{
long long xa
, xb
, ya
, yb
, xc
, xd
, yc
, yd
;
long long Ax1
, Ax2
, Ay1
, Ay2
;
int t1
= xa_id
, t2
= ( xa_id
) % a
+ 1 ;
xa
= A
[ t1
] [ 0 ] - A
[ t1
+ 1 ] [ 0 ] ;
xb
= A
[ t1
] [ 0 ] - A
[ ( t1
+ 2 ) % a
+ 1 ] [ 0 ] ;
ya
= A
[ t1
] [ 1 ] - A
[ t1
+ 1 ] [ 1 ] ;
yb
= A
[ t1
] [ 1 ] - A
[ ( t1
+ 2 ) % a
+ 1 ] [ 1 ] ;
xc
= A
[ t2
] [ 0 ] - A
[ t2
+ 1 ] [ 0 ] ;
xd
= A
[ t2
] [ 0 ] - A
[ ( t2
+ 2 ) % a
+ 1 ] [ 0 ] ;
yc
= A
[ t2
] [ 1 ] - A
[ t2
+ 1 ] [ 1 ] ;
yd
= A
[ t2
] [ 1 ] - A
[ ( t2
+ 2 ) % a
+ 1 ] [ 1 ] ;
if ( xa
* xb
+ ya
* yb
> 0 )
{
Ax1
= xa
;
Ax2
= xb
;
Ay1
= ya
;
Ay2
= yb
;
}
else
{
Ax1
= xc
;
Ax2
= xd
;
Ay1
= yc
;
Ay2
= yd
;
}
long long xat
, xbt
, yat
, ybt
, xct
, xdt
, yct
, ydt
;
long long Bx1
, Bx2
, By1
, By2
;
int tt1
= xb_id
, tt2
= ( xb_id
) % b
+ 1 ;
xat
= B
[ tt1
] [ 0 ] - B
[ tt1
+ 1 ] [ 0 ] ;
xbt
= B
[ tt1
] [ 0 ] - B
[ ( tt1
+ 2 ) % b
+ 1 ] [ 0 ] ;
yat
= B
[ tt1
] [ 1 ] - B
[ tt1
+ 1 ] [ 1 ] ;
ybt
= B
[ tt1
] [ 1 ] - B
[ ( tt1
+ 2 ) % b
+ 1 ] [ 1 ] ;
xct
= B
[ tt2
] [ 0 ] - B
[ tt2
+ 1 ] [ 0 ] ;
xdt
= B
[ tt2
] [ 0 ] - B
[ ( tt2
+ 2 ) % b
+ 1 ] [ 0 ] ;
yct
= B
[ tt2
] [ 1 ] - B
[ tt2
+ 1 ] [ 1 ] ;
ydt
= B
[ tt2
] [ 1 ] - B
[ ( tt2
+ 2 ) % b
+ 1 ] [ 1 ] ;
if ( xat
* xbt
+ yat
* ybt
> 0 )
{
Bx1
= xat
;
Bx2
= xbt
;
By1
= yat
;
By2
= ybt
;
}
else
{
Bx1
= xct
;
Bx2
= xdt
;
By1
= yct
;
By2
= ydt
;
}
if ( ( Ax1
* Ax2
+ Ay1
* Ay2
) * ( Ax1
* Ax2
+ Ay1
* Ay2
) * ( Bx1
* Bx1
+ By1
* By1
) *
( Bx2
* Bx2
+ By2
* By2
) != ( Bx1
* Bx2
+ By1
* By2
) * ( Bx1
* Bx2
+ By1
* By2
) * ( Ax1
* Ax1
+ Ay1
* Ay1
) *
( Ax2
* Ax2
+ Ay2
* Ay2
) )
{
printf ( "NO\n" ) ;
continue ;
}
}
printf ( "YES\n" ) ;
continue ;
}
printf ( "NO\n" ) ;
}
return 0 ;
}
總結
以上是生活随笔 為你收集整理的东北大学第二场算法题解报告 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。