標籤:
1 //組合數學 2 //計算sum{i從右往左數的第一個非0數字,p<=i<=q}。 3 #include <cstdio> 4 typedef long long ll; 5 6 ll sum(ll n) 7 { 8 ll ans = 0, x; 9 while(n)10 {11 x = n % 10;12 n /= 10;13 ans += ((1 + x) * x) / 2 + n * 45; //當個位在迴圈的時候,高位的朋友你在幹嘛?14 }15 return ans;16 }17 18 int main()19 {20 ll a, b;21 while(scanf("%lld%lld", &a, &b), a >= 0)22 {23 printf("%lld\n", sum(b) - sum(a - 1));24 }25 return 0;26 }
題目大意:給出l和r,求∑(l≤i≤r)F(i), F(i)函數題目中有。
解題思路:由兩邊向中間縮排,然後l和r之間的數可以按照1~9劃分(只會有這幾種情況)。
1 #include <stdio.h> 2 #define ll long long 3 ll ans; 4 5 ll f(ll x) { 6 if (x == 0) return 0; 7 else if (x % 10) 8 return x % 10; 9 else10 return f(x / 10);11 }12 13 void solve(ll l, ll r) {14 if (r - l < 9) {15 for (int i = l; i <= r; i++)16 ans += f(i);17 return;18 }19 20 while (l % 10) {21 ans += f(l);22 l++;23 }24 25 while (r % 10) {26 ans += f(r);27 r--;28 }29 ans += 45 * (r - l) / 10;30 solve(l / 10, r / 10);31 }32 33 int main () {34 ll l, r;35 while (scanf("%lld%lld", &l, &r), l >= 0 || r >= 0) {36 ans = 0;37 solve(l, r);38 printf("%lld\n", ans);39 }40 return 0;41 }
其實只要看題目推敲一下,大概可以知道其實就是各個數字最低階不是0的數字的總和。
可將題目要加的拆成各個位數來做,每一個位數都要考慮%10和/10的情況要加多少,將這些值全部加起來即可得解。
P.S. 雖然p,q可以在32bits整數下存放,但可沒說總和也可以喔!
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 5 int main(){ 6 long long p, q; 7 long long sum; 8 9 while( scanf( "%lld%lld", &p, &q ) != EOF && !( p < 0 && q < 0 )){10 sum = 0;11 12 while( p || q ){13 sum += (q%10+p%10)*((q%10)-(p%10)+1)/2;14 sum += (q/10-p/10)*45;15 16 if( p%10 && (p/10 || q/10) ) p += 10;17 p /= 10;18 q /= 10;19 }20 21 printf( "%lld\n", sum );22 }23 return 0;24 }
uva 10994 - Simple Addition