UVA计数方法练习[3]

UVA - 11538

Chess Queen

题意:n*m放置两个互相攻击的后的方案数

分开讨论行 列 两条对角线

一个求和式

可以化简后计算

//
//  main.cpp
//  uva11538
//
//  Created by Candy on 24/10/2016.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
inline ll read(){
    char c=getchar();ll x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}
ll n,m;
int main(int argc, const char * argv[]) {
    while((n=read())){
        m=read();
        if(n>m) swap(n,m);
        ll ans=m*(m+n-2)*n+2*n*(n-1)*(3*m-n-1)/3;
        printf("%lld\n",ans);
    }

    return 0;
}



UVA - 11401

Triangle Counting

题意:1到n选三个不相同的数组成三角形的方案数

考虑以i为最大边的三角形,i-y<z<i

(i-1)*(i-2)/2 再减去剩下y==z的情况,i/2+1....i-1都可以相等

//
//  main.cpp
//  uva11401
//
//  Created by Candy on 24/10/2016.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1e6+5;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}
ll f[N],n;
void dp(){
    f[3]=0;
    for(ll i=4;i<=1e6;i++)
        f[i]=f[i-1]+((i-1)*(i-2)/2-(i-1-i/2))/2;
}
int main(int argc, const char * argv[]) {
    dp();
    while((n=read())>=3){
        printf("%lld\n",f[n]);
    }
    return 0;
}



UVA - 11806

Cheerleaders

题意:n*m放k个石子,第一行最后一行第一列最后一列都要有

没有的话很好求就是个组合数

二进制枚举集合,利用容斥原理的变式奇负偶正

//
//  main.cpp
//  uva11806
//
//  Created by Candy on 24/10/2016.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=505,MOD=1000007;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}
int T,n,m,k,f[N][N];
void init(){
    f[0][0]=1;
    for(int i=1;i<=500;i++){
        f[i][0]=f[i][i]=1;
        for(int j=1;j<i;j++) f[i][j]=(f[i-1][j]+f[i-1][j-1])%MOD;
    }
}
int main(int argc, const char * argv[]) {
    init();
    T=read();int cas=0;
    while(T--){cas++;
        n=read();m=read();k=read();
        int ans=0;
        for(int S=0;S<16;S++){
            int b=0,r=n,c=m;
            if(S&1) r--,b++;
            if(S&2) r--,b++;
            if(S&4) c--,b++;
            if(S&8) c--,b++;
            if(b&1) ans=(ans-f[r*c][k]+MOD)%MOD;
            else ans=(ans+f[r*c][k])%MOD;
        }
        printf("Case %d: %d\n",cas,ans);
    }

    return 0;
}
时间: 2024-08-07 19:35:46

UVA计数方法练习[3]的相关文章

数学基础——基本计数方法

计数方法最基础的两个原理是:加法原理和乘法原理. 容斥原理: 假设一个班里有10个学生喜欢数学,15个学生喜欢语文,21个学生喜欢编程.那么班级总人数: |A∪B∪C| = |A| + |B| + |C| - |A∩B| - |A∩C| - |B∩C| + |A∩B∩C| 一般的,任意多个集合,集合内的元素个数为奇数,前面的符号为正. 问题1:排列问题 n个不同的数,选k个排成1排,有多少种排法. 答案计做p(n,k) = n*(n-1)*(n-2)*...*(n-(k-1)) = n!/(n-

Overflow UVA 465 方法二求纠错

注明: 本题使用了两种解法,第一种参考了网上一种非常普遍的解法,即使用atof函数将两个数字字符串转化为两个浮点数,然后直接和int的最大值比较即可.这种方法较简单,不过也是在数据较小的情况下行得通.而第二种是我自己写的一种更较为普遍的解法,其实也就是直接根据字符串进行高精度的运算而已.自己用了很多数据进行测试都没有错,可是就是AC不了,不知道为什么.希望大神指教!!! 题目: Overflow Write a program that reads an expression consistin

学习总结--数学.基本计数方法

学习总结--数学.基本计数方法 一.计数方法的原理 1.加法原理:做一件事情有n中办法,第i种办法有pi种执行方案,那么总的解决这件事情的方案数即为p1+p2+p3+...+pn. 2.乘法原理:做一件事情分为n个步骤,第i个步骤的执行方案有pi种,则一共有p1?p2?p3?...?pn种方案解决该问题. 3.容斥原理:一个班级有,集合A的人喜欢数学,集合B的人喜欢英语,结合C的人喜欢语文,那么该班级的人数应该是多少? 如果我们将三个集合的人数相加起来,那么就重复计算了既喜欢数学又喜欢英语的.既

【基本计数方法---加法原理和乘法原理】UVa 11538 - Chess Queen

题目链接 题意:给出m行n列的棋盘,当两皇后在同行同列或同对角线上时可以互相攻击,问共有多少种攻击方式. 分析:首先可以利用加法原理分情况讨论:①两皇后在同一行:②两皇后在同一列:③两皇后在同一对角线( / 或 \ ): 其次利用乘法原理分别讨论: ①同一行时(A),先选某一行某一列放置其中一个皇后,共m*n种情况:其次在选出的这一行里的其他n-1个位置中选一个放另一个皇后:共m*n*(n-1)种情况: ②同一列时(B)情况相同,为n*m*(m-1)种情况: ③同一对角线(D)上时,先讨论 /

【组合数学】 05 - 经典计数方法

1. 基本计数的母函数 现在来用母函数来求解基本计数问题,母函数既可以完成自动计数,还能表示计数本身,像Stirling数这种就只能用母函数表示.自动计数适用于可以分步的计数问题,并且目标值是每步值之和,这与多项式的运算性质有关. 1.1 组合数和分划数 直观上最符合这一特点的就是模型2,从\(n\)个可区别对象中选出\(m个\).限制第\(k\)个对象被取的次数在集合\(M_k\)中,它被选情况的母函数是\(\sum\limits_{i\in M_k}x^i\),所有元素被选择的情况可以借助母

算法竞赛入门经典行训练指南【计数方法】------2015年1月23日

基础知识整理: (1)加法原理 (2)乘法原理 (3)容斥原理(注意变式问题) (4)排列组合公式的应用及变形: 排列的公式: 其变形为: 与组合的关系如下(以下第一个公式很重要): 排列组合公式的重要推论: 推论1: 对于第一个物体如果不取的话,那么我们有C(n,k+1)种方法,对于第一个物体取的话,我有C(n,k)种方法.公式得证. 推论2: 这可以降低求解二项式系数的时间复杂度,通过利用递推关系自小到大依次计算得出,方便快捷. (5)排列组合的基本问题: Q1:求有重复元素的排列. 有k个

php导出excel长数字串显示为科学计数方法与最终解决方法

1.设置单元格为文本 $objPHPExcel = new PHPExcel(); $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getActiveSheet()->setTitle('Simple');//设置A3单元格为文本 $objPHPExcel->getActiveSheet()->getStyle('A3')->getNumberFormat()->setFormatCode(PHPExcel_

2.1 基本计数方法

例题1 uva 11538 http://acm.hust.edu.cn/vjudge/problem/28978 在m*n棋盘上放置 黑白两个皇后,相互攻击的方法数. 解法,正着考虑, 同行,同列, 斜着的情况加在一起, 组合书计算一下, 黑白不同 所以是 P(n,2). 对斜着的角的情况暴力算也过. 1760ms 1 //#define txtout 2 //#define debug 3 #include<bits/stdc++.h> 4 #define mt(a,b) memset(a

算法竞赛训练指南2.1 计数方法

1. O(n)方法求C(n,m) 利用公式C(n,k+1)=C(n,k)*(n-k)/(k+1) 模板: #include <iostream> #include <algorithm> using namespace std; typedef unsigned long long LL; const int maxn=100005; LL n,m; LL C() { if(m==0||n==m) return 1; if(m>n-m) m=n-m; LL ans,temp=