2013四川省赛(G,K)

一个自闭的下午,源于看错题了QAQ。G题是一个数字的总和是10的倍数就行,我当成了等于10。K题a、b的长度不超过1e6,读成了a、b的值不超过了1e6。o(╥﹏╥)o
G - Good Numbers
K - Kia’s Calculation

G - Good Numbers

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722
题意:一个数,每一个数位相加的和sum,若sum是10的倍数,那么这个数就是一个good number。给出a,b。求[a, b]内good number的个数。
解法:假设,一个数val,数位和sum,最后一位是x,(sum - x ) % 10 <= 9。易得规律:每数10个数,则里面必有且只有一个good number。
故[0, val]内good number的个数num([0, val]),无非就两种情况,val / 10 + 1 或者 val / 10。
num([a, b]) = num([0, b]) - num([0, a- 1])。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define db1(x) cout << #x << " = " << x << endl;
const double eps = 1e-6;
const int N = 2e3 + 10;
const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1} };
void FAST() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
}

ll dsum(ll x) {
    ll sum = 0;
    while(x) {
        sum += (x % 10);
         x /= 10;
    }
    return sum;
}

ll cal(ll x) {
    ll ans = x / 10;
    for (ll i = x / 10 * 10; i <= x; ++ i) {
        ll sum = dsum(i);
        if(sum % 10 == 0) return ans + 1;
    }
    return ans;
}

void solve(int T) {
    ll a, b; scanf("%lld%lld", &a, &b);
    ll ans = cal(b) - cal(a - 1);
    printf("Case #%d: %lld\n", T, ans);
}

int main() {
//    FAST();
    int cnt = 0;
    int T; scanf("%d", &T); while(T--) solve(++ cnt);
    return 0;
}

K - Kia’s Calculation

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4726
题意:Kia在进行加法运算的时候总是忘记进位。eg:4567 + 5789,kia会得到9246。Kia可以随便改变一个数中的每个数位上数的次序(但新数中不能含前导0,新数的长度与原数相同)。eg:11220,Kia可以将它变成12120,01122(不合法)。给两个数a、b。a, b的数位相同,其数位<1e6,无前导0。计算a + b。求Kia可以得到的最大值。
解法:贪心,第一位无0特判。取出的数x, y。另他们尽可能小。但x+y最大。eg:280 , 480。显然2,4才是正确的。
后面的枚举可以取出的最大和,这里的x,y不用管,因为后续没有新数字加入,无影响。
注意:多余的前导0不需要输出。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define db1(x) cout << #x << " = " << x << endl;
const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1} };
void FAST() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
}
const int N = 1e6 + 10;
char s1[N], s2[N];
int a[11], b[11], c[N];

void solve(int T) {
    scanf("%s %s", s1, s2);
    int len = strlen(s1);
    if(len == 1) {
        int ans = s1[0] - '0' + s2[0] - '0';
        ans %= 10;
        printf("Case #%d: %d\n", T, ans);
        return ;
    }
    for (int i = 0; i < len; ++ i) a[s1[i] - '0'] ++, b[s2[i] - '0'] ++;
    int mx = -1, pi, pj;
    for (int i = 1; i <= 9; ++ i) {
        if(!a[i]) continue;
        for (int j = 1; j <= 9; ++ j) {
            if(!b[j]) continue;
            int p = (i + j) % 10;
            if(p > mx) {mx = p; pi = i; pj = j; }
        }
    }
    c[0] = 0;
    c[++c[0]] = mx;
    a[pi] --; b[pj] --;
    for (int i = 9; i >= 0; -- i) {
        for (int j = 0; j <= 9; ++ j) {
            if(!a[j]) continue;
            int tmp = (i - j + 10) % 10;
            if(b[tmp]) {
                int mi = min(a[j], b[tmp]);
                a[j] -= mi; b[tmp] -= mi;
                while(mi -- ) c[++c[0]] = i;
            }
        }
    }
    int s = 1;
    while(c[s] == 0 && s <= c[0]) ++ s;
    s = min(s, c[0]);
    printf("Case #%d: ", T);
    for (int i = s; i <= c[0]; ++ i) printf("%d", c[i]);
    printf("\n");
}

int main() {
//    FAST();
    int cnt = 0;
    int T; scanf("%d", &T); while(T--) solve(++ cnt);
    return 0;
}
发布了10 篇原创文章 · 获赞 9 · 访问量 3072
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览