算法竞赛入门经典——训练指南

本文解析了UVa11300和UVa11806两个算法题目。对于UVa11300,通过排序和计算绝对值差的方法求解;UVa11806则运用了容斥原理解决在限定条件下放置石子的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. UVa 11300

我的代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

long long C[1000010], M, a;
int main() {
    int n;
    while (~scanf("%d", &n)) {
        C[0] = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &a);
            C[i] = C[i-1]+a;
        }
        M = C[n]/n;
        for (int i = 1; i < n; i++) C[i] -= i*M;
        sort(C, C+n);
        long long ans = 0, x = C[n/2];
        for (int i = 0; i < n; i++) ans += abs(x-C[i]);
        cout<<ans<<endl;
    }
}
View Code

 

2.UVa 11806

题意:在m行n列里放k个相同的石子,每个格子只能放一个,并且第一行、最后一行、第一列、最后一列必须有石子,输出总方案数模1000007的余数(2<=m,n<=20  k<=500)

关键词:容斥原理,集合表示

思路:容斥原理。集合A,B,C,D分别表示“第一行没有石子”、“最后一行没有石子”、“第一列没有石子”、“最后一列没有石子”,全集为S,那么所求答案即为“在S中而不在A,B,C,D中”的元素个数,容斥原理求解。用二进制表示四个集合的16种搭配,若最后剩r行c列,显然方法数为C(rc,k)。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 510;
const int mod = 1000007;
int C[maxn][maxn];
void init() {
    memset(C, 0, sizeof(C));
    for (int i = 0; i < maxn; i++) {
        C[i][0] = C[i][i] = 1;
        for (int j = 1; j < i; j++)
            C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
    }
}
int main() {
    int T, m, n, k;
    init();
    cin>>T;
    for (int t = 1; t<= T; t++) {
        int sum = 0;
        cin>>m>>n>>k;
        for (int s = 0; s < 16; s++) {  ///枚举16种搭配方式
            int b = 0, r = m, c = n;    ///集合数,行数,列数
            if (s&1) r--, b++;  ///第一行没石头
            if (s&2) r--, b++;  ///最后一行没石头
            if (s&4) c--, b++;  ///第一列没石头
            if (s&8) c--, b++;  ///最后一列没石头
            if (b&1) sum = (sum + mod - C[r*c][k]) % mod;   ///奇数个条件做减法
            else sum = (sum + C[r*c][k]) % mod;             ///偶数个条件做加法
        }
        cout<<"Case "<<t<<": "<<sum<<endl;
    }
}
View Code

 

转载于:https://www.cnblogs.com/hqxue/p/6618635.html

算法竞赛入门经典——训练指南》代码仓库 例题代码 限于篇幅,书上并没有给出所有例题的代码,这里给出了所有例题的代码,并且改进了书上的一些代码。 第一章 32题 38份代码 第二章 28题 30份代码 第三章 22题 23份代码 第四章 19题 21份代码 第五章 34题 39份代码 第六章 24题 26份代码 共159题 177份代码 为了最大限度保证代码风格的一致性,所有例题代码均由刘汝佳用C++语言编写。 所有代码均通过了UVa/La的测试,但不能保证程序是正确的(比如数据可能不够强),有疑问请致信rujia.liu@gmail.com,或在googlecode中提出: http://code.google.com/p/aoapc-book/ [最新更新] 2013-04-23 增加字符串中例题10(UVa11992 Fast Matrix Operations)的另一个版本的程序,执行效率较低,但更具一般性,可读性也更好 2013-04-22 增加字符串部分“简易搜索引擎”代码,可提交到UVa10679 2013-04-13 修正Treap中优先级比较的bug(原来的代码实际上是在比较指针的大小!),加入纯名次树代码 2013-03-31 修正UVa1549标程的bug,即buf数组不够大。 增加线段树部分“动态范围最小值”的完整代码 2013-03-23 修正UVa10054标程的bug,即没有判断是否每个点的度数均为偶数。UVa数据已经更新 LA3401修正了代码和文字不一致的问题 UVa11270增加了答案缓存 2013-03-21 增加线段树部分中两个经典问题的完整代码:快速序列操作I和快速序列操作II 2013-02-28 补全所有159道例题的代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值