生活随笔
收集整理的這篇文章主要介紹了
[蓝桥杯][2015年第六届真题]表格计算(递归+记忆化)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述 某次無聊中, atm 發現了一個很老的程序。這個程序的功能類似于 Excel ,它對一個表格進行操作。 不妨設表格有 n 行,每行有 m 個格子。 每個格子的內容可以是一個正整數,也可以是一個公式。 公式包括三種:
SUM(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 個格子,右下角是第 x2 行第 y2 個格子這個矩形內所有格子的值的和。 AVG(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 個格子,右下角是第 x2 行第 y2 個格子這個矩形內所有格子的值的平均數。 STD(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 個格子,右下角是第 x2 行第 y2 個格子這個矩形內所有格子的值的標準差。
標準差即為方差的平方根。 方差就是:每個數據與平均值的差的平方的平均值,用來衡量單個數據離開平均數的程度。
公式都不會出現嵌套。
如果這個格子內是一個數,則這個格子的值等于這個數,否則這個格子的值等于格子公式求值結果。
輸入這個表格后,程序會輸出每個格子的值。atm 覺得這個程序很好玩,他也想實現一下這個程序。 輸入 第一行兩個數 n, m 。 接下來 n 行輸入一個表格。每行 m 個由空格隔開的字符串,分別表示對應格子的內容。 輸入保證不會出現循環依賴的情況,即不會出現兩個格子 a 和 b 使得 a 的值依賴 b 的值且 b 的值依賴 a 的值。
輸出 輸出一個表格,共 n 行,每行 m 個保留兩位小數的實數。 數據保證不會有格子的值超過 1e6 。 樣例輸入 3 2 1 SUM(2,1:3,1) 2 AVG(1,1:1,2) SUM(1,1:2,1) STD(1,1:2,2) 樣例輸出 1.00 5.00 2.00 3.00 3.00 1.48 思路:其實這個題目看著比較麻煩,但是思路還是比較好想的。我們利用字符串二維數組先儲存起來,然后對于那些沒有直接給出的數值,遞歸去求。求出來之后就將結果保存,以免重復求。 代碼如下:
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a,b,c) for(int i=1;i<=b;i++) for(int j=1;j<=b;j++) a[i][j]=-1.0;
using namespace std
; const int maxx
= 101 ;
string s
[ maxx
] [ maxx
] ;
double ans
[ maxx
] [ maxx
] ;
int a
[ 5 ] ;
int n
, m
; inline double getval ( int x
, int y
)
{ string t
= s
[ x
] [ y
] ; if ( ans
[ x
] [ y
] != - 1.0 ) return ans
[ x
] [ y
] ; if ( t
[ 0 ] >= '0' && t
[ 0 ] <= '9' ) { double sum
= 0.0 ; for ( int i
= 0 ; i
< t
. length ( ) ; i
++ ) sum
= sum
* 10.0 + ( t
[ i
] - '0' ) ; return ans
[ x
] [ y
] = sum
; } int num
= 0 , j
; memset ( a
, 0 , sizeof ( a
) ) ; for ( int i
= 0 ; i
< t
. length ( ) ; ) { if ( t
[ i
] >= '0' && t
[ i
] <= '9' ) { j
= i
; while ( j
< t
. length ( ) && t
[ j
] >= '0' && t
[ j
] <= '9' ) a
[ num
] = a
[ num
] * 10 + ( t
[ j
++ ] - '0' ) ; i
= j
; num
++ ; } else i
++ ; } double sum
= 0 ; for ( int i
= a
[ 0 ] ; i
<= a
[ 2 ] ; i
++ ) for ( int j
= a
[ 1 ] ; j
<= a
[ 3 ] ; j
++ ) sum
+ = getval ( i
, j
) ; if ( t
[ 1 ] == 'U' ) return ans
[ x
] [ y
] = sum
; else if ( t
[ 1 ] == 'V' ) return ans
[ x
] [ y
] = sum
/ ( double ) ( ( a
[ 2 ] - a
[ 0 ] + 1 ) * ( a
[ 3 ] - a
[ 1 ] + 1 ) ) ; else { double avg
= sum
/ ( double ) ( ( a
[ 2 ] - a
[ 0 ] + 1 ) * ( a
[ 3 ] - a
[ 1 ] + 1 ) ) ; double ans1
= 0.0 ; for ( int i
= a
[ 0 ] ; i
<= a
[ 2 ] ; i
++ ) for ( int j
= a
[ 1 ] ; j
<= a
[ 3 ] ; j
++ ) { double xx
= getval ( i
, j
) ; ans1
+ = ( xx
- avg
) * ( xx
- avg
) ; } return ans
[ x
] [ y
] = sqrt ( ans1
/ ( double ) ( ( a
[ 2 ] - a
[ 0 ] + 1 ) * ( a
[ 3 ] - a
[ 1 ] + 1 ) ) ) ; }
}
int main ( )
{ scanf ( "%d%d" , & n
, & m
) ; mem ( ans
, n
, m
) ; for ( int i
= 1 ; i
<= n
; i
++ ) for ( int j
= 1 ; j
<= m
; j
++ ) cin
>> s
[ i
] [ j
] ; for ( int i
= 1 ; i
<= n
; i
++ ) for ( int j
= 1 ; j
<= m
; j
++ ) ans
[ i
] [ j
] = getval ( i
, j
) ; for ( int i
= 1 ; i
<= n
; i
++ ) for ( int j
= 1 ; j
<= m
; j
++ ) printf ( "%.2lf%c" , ans
[ i
] [ j
] , j
== m
? '\n' : ' ' ) ; return 0 ;
}
努力加油a啊,(o )/~
總結
以上是生活随笔 為你收集整理的[蓝桥杯][2015年第六届真题]表格计算(递归+记忆化) 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。