題目大意:
將 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...