Spoj 1433 數字問題

2021-06-18 14:56:13 字數 3627 閱讀 4315

題目大意:

將 1~n(1<=n<= 15 10 )寫在紙上,然後在相鄰的數字間交替插入」+」和」-「,求最後的

結果。例如當 n 為 12 時,答案為:+1-2+3-4+5-6+7-8+9-1+0-1+1-1+2=5

解法分析:

這是一道稍微複雜一點的數字計數問題。

根據上述原則,我們首先探查數字確定,所有數字自由的情況。

若數字數為偶數,以 6 位為例(不妨設第乙個符號為+):

+0  -0  +0  -0  +0  -0

+0  -0  +0  -0  +0  -1

+0  -0  +0  -0  +0  -2

………………………………………………………

+9  -9  +9  -9  +9  -9

此時,每乙個數字的符號都是確定的,因此只需要分別計算每一位的所有數字和即可,

因為所有位 0~9 出現機會均等,因此和必然為 0。

若數字數為奇數,此情況更加簡單,以 5 位為例(不妨設第乙個符號為+) :

+0  -0  +0  -0  +0

-0  +0  -0  +0  -1

+0  -0  +0  -0  +2

-0  +0  -0  +0  -3 

………………………………………………………

+9  -9  +9  -9  +8

-9  +9  -9  +9  -9

可以注意到,相鄰兩行的和必然為-1,因此整個和很容易求出。

於是我們編寫函式 getsum1 和檢驗函式 check。 (getsum1 的另乙個引數 k 的由來在下頁

有說明)

long long getsum1( int n, int k )

//n 為自由位個數,k 為總位數(k>=n>=1) }

else

} long long check( int n )

for (int j = r - 1; j >= 0; j-- ) }

return ret;

} 接下來,考慮帶有字首的情況,因為字首對符號的影響,所以需要在 getsum1 處追加總

位數的引數。此時由 getsum1 處可求出自由位的數字和,因此只需再求出字首的數字和即可。

當總位數=自由位+字首位數為偶數時:

+1  -2  +0  -0  +0  -0

+1  -2  +0  -0  +0  -1

+1  -2  +0  -0  +0  -2

………………………………………………………

+1  -2  +9  -9  +9  -9

字首數字和符號不變,因此只需要乘總行數即可。

總位數為奇數時:

+1  -2  +0  -0  +0

-1  +2  -0  +0  -1

+1  -2  +0  -0  +2

-1  +2  -0  +0  -3

清華附中 高逸涵

第 8 頁 共 13 頁

………………………………………………………

+1  -2  +9  -9  +8

-1  +2  -9  +9  -9

字首兩兩相消,和為 0。

依照以上分析編寫 getsum2。

long long getsum2( long long prefix, int n )

//prefix 為字首,n 為自由位個數(n >= 1, prefix >= 1)

presum *= -t;

for (int i = 0; i < n; i++ ) presum *= 10;

long long ret = getsum1( n, n + d );

if ( (d + n) % 2 == 0 ) ret += presum;

return ret;

} 沿用上例的思路,再有了上述兩個函式之後,我們繼續將整個區間劃分為若干段,分別

利用上述函式求和,這裡不再重複敘述,只是將函式實現展示如下。(不能沿用上例遞迴程

序是由於上例新增前導 0 對結果不影響,而本例則不同)

long long getsum3( long long n )

//對原問題進行求和[1,n],n>=1

long long tn = n, p = 1;

int d = 0;

while ( tn > 0 )

for (int i = 1; i < d; i++ ) p *= 10;

long long prefix = 0, ret = 5;

for (int j = 1; j < d - 1; j++ )

for (int i = 1; i <= 9; i++ )

ret -= getsum2( i, j );

tn = n;

while (d > 1)

tn %= p; p /= 10; 

d--; prefix *= 10;

} int a[20], t = -1;

for (int i = 0; i <= tn; i++ )

for (int j = r - 1; j >= 0; j-- ) }

return ret;

} ac**如下:

#include #include #include #include #include using namespace std;

long long getsum1( long long n, long long k )else

return ans;

} }else

return ans / 2; }}

long long getsum2( long long prefix, long long n )

presum *= -t;

for( int i = 1; i <= n; i++ )

ans += getsum1( n, n + d );

if( ( n + d ) % 2 == 0 )

return ans;

}long long getsum3( long long n )else

} return ans;

} long long ans = 5;

long long d = 0, tn = n, p = 1;

while( tn > 0 )

for( int j = 1; j < d - 1; j++ )

} for( int i = 1; i < d; i++ )

tn = n;

long long prefix = 0;

while( d > 1 )

prefix++;

} prefix *= 10;

tn %= p;

p /= 10;

d--;

} int a[20], r = 0, t = -1;

for( int i = 0; i <= tn; i++ )

for( int j = r - 1; j >= 0; j-- )

} return ans;

}int main()

return 0;

}

spoj 1433 The Sum 數字統計

高逸涵的 數字計數問題解法研究 第乙個例題 講解的很詳細 也是數字統計的入門訓練吧 題意 輸入乙個數n 輸出從1到n每個數的每位 十進位制 以 迴圈處理的和 for example,if n 12 then 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 5 按 的的想法分奇偶進行統計即...

1433 數碼問題

題目 這套比賽因為當時做的太差,所以這道剛剛一眼看出的題目也寫一下吧。完全不知道為什麼當時我這題會爆0?k 1000,很明顯的暴力也能過啊。對於第i個數,如果知道了它的座標,答案顯然。那麼對於第i個數,我們就拿它去更新其它的與它同一行的,更新完同一行之後再更新同一列,就可以啦 var x,r,c,x...

sql埠1433錯誤的問題

正在連線127.0.0.1.無法開啟到主機的連線。在埠 1433 連線失敗 解決方案 先防火牆新建規則 埠1433 結果沒用!cmd先輸入telnet localhost 1433 發現還是 正在連線localhost 無法開啟到主機的連線。在埠 1433 連線失敗 開啟配置管理器,找到 sql s...