整理的算法模板合集: ACM模板
这次比赛好多原题呀…(就是那种稍微拓展了一点的原题)
目录
A、Easy Equation
题目大意:求 x + y + z = k x+y+z=k x+y+z=k的方案数,输入为四个数可取的范围。
前缀和差分。
首先一看数据范围是1e6就不可能 O ( n 2 ) O(n^2) O(n2)做,只能 O ( n ) O(n) O(n)。
之前做过一道简化版的题,是求 x + y = z x+y=z x+y=z的方案数,用的好像是什么前缀和映射思想,我忘了,是CF上面的一次比赛题,但是我找不到了…这里是三个,所以把那个方法拓展一下即可。
实际上用前缀和来解决思路特别简单,大致是一个前缀和+递推DP的思想。
因为有三个数相加的方案数
我们用 f[i]
表示i
能够被多少个前两个范围的数(x+y)加起来的方案数,我们直接循环x,那么所有从 x
到 x+b
的数都能被这个数递推过去,方案数+1,我们可以直接用前缀和来维护一个区间+1的操作,这样求得 f
数组,然后我们用同样的思路求g数组,其中g[i]
表示的是i能够被多少个x+y+z的方案数,同样的我们维护一个前缀和差分,再求一次前缀和就是所有能通过x+y+z得到这个数的方案数,我们直接枚举所有d的范围,求和既是答案。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
const int N = 1e8 + 7, M = 5000007, INF = 0x3f3f3f3f;
long long a, b, c, d;
long long f[N];
long long g[N];
int main()
{
scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
for(int i = 0; i <= a; ++ i){
f[i] ++ ;
f[i + b + 1] -- ;
}
for(int i = 1; i <= a + b; ++ i)
f[i] += f[i - 1];
for(int i = 0; i <= a + b; ++ i){
g[i] += f[i];
g[i + c + 1] -= f[i] ;
}
for(int i = 1 ;i <= a + b + c; ++ i)
g[i] += g[i - 1];
long long ans = 0;
for(int i = 0; i <= d; ++ i)
ans += g[i];
printf("%lld\n", ans);
return 0;
}
B、XTL’s Chessboard
题目大意:弹弹弹
SB题,直接输出2就行了,因为所有的点沿着45度角射出反弹最后都会回到起点,x-1和y-1互质的时候一定会经过角,就会直接反弹原路返回。所以只有起点和终点经过奇数次,答案就是2。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
const int N = 500007, M = 5000007, INF = 0x3f3f3f3f;
int n, m, t;
int a[N], b[N];
bool vis[N];
int ans;
int main()
{
int x, y;
while(scanf("%d%d%d%d", &n, &m, &x, &y) != EOF && n + m){
printf("2\n");
}
return 0;
}
D、Pokemon Ultra Sun
题目大意:宝可梦们大战,你和对手都有一个血量,每一轮都是你打对手,攻击力为w,每次有p的概率对手掉血,1-p的概率你自己掉血,求比赛轮数的期望。
概率DP板子题…
我们用 f[i][j]
表示我方掉i
血敌方掉j
血的期望。
然后直接输出即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
const int N = 3507, M = 5000007, INF = 0x3f3f3f3f;
int n, m, t;
int hp1, hp2, w;
double f[N][N];
double p;
int main()
{
scanf("%d", &t);
while(t -- ){
scanf("%d%d%d%lf", &hp1, &hp2, &<