A:两个正整数n,k,1 <= n,k <= 25;
n种不同食材,每种都有无限多,从中选出k个,可选择相同食材,问有多少种选法,显然答案为Cmn(n+k-1,k)种
由于n,k不大,最多不过是Cmn(50,25),故直接打表即可
时间复杂度:O(1);
//#include <bits/stdc++.h>
//#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <ctime>
/*
int gcd(int a,int b)
{
return ! b ? a : gcd(b,a % b);
}
struct data
{
int val;
int pos;
int ranks;
}p[2005];
typedef struct
{
double x,y;
}Point;
bool cmp1(const data &a,const data &b)
{
if(a.val == b.val)
return a.pos < b.pos;
return a.val < b.val;
}
bool cmp2(const data &a,const data &b)
{
return a.val > b.val;
}
bool cmp3(const data &a,const data &b)
{
return a.pos < b.pos;
}
const double ERR = 0.0001;
bool feq (double a, double b)
{
return fabs(a-b) < ERR;
}
double fgcd(double a, double b)
{
if (feq(a, 0))
return b;
if (feq(b, 0))
return a;
return fgcd(b, fmod(a, b));
}
double dist(double x0, double x1, double y0, double y1)
{
return sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
}
*/
#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9 + 7;
using namespace std;
LL Cmn[105][105];
int main()
{
ios_base::sync_with_stdio(false); cin.tie(0);
//freopen("int.txt","r",stdin);
//freopen("out.txt","w",stdout);
memset(Cmn,0,sizeof(Cmn));
for(int i = 1;i < 100;i++)
Cmn[i][0] = 1;
Cmn[0][0] = 1;
for(int i = 1;i < 100;i++)
for(int j = 1;j <= i;j++)
Cmn[i][j] = Cmn[i - 1][j] + Cmn[i - 1][j - 1];
/*
for(int i = 1;i < 25;i++)
{
for(int j = 0;j <= i;j++)
printf("%d ",Cmn[i][j]);
puts("");
}
*/
int n,k;
scanf("%d %d",&n,&k);
printf("%lld\n",Cmn[n + k - 1][k]);
return 0;
}
B:博弈论题目,求先手的必败态和必胜态,不过貌似要用DP求解
C:中国剩余定理的变形,只不过这里的ni之间并没说是两两互素。
本题是一元线性同余方程组的求解。即对所有方程依次进行合并。
用合并后的方程再来和其他的方程按这样的方式进行合并,最后就能只剩下一个方程 X mod M=R,其中 M=LCM(m1,m2,…,mn)。
用拓展GCD求解
坑点在于开始得先把起点放到最小,即先取模
//#include <bits/stdc++.h>
//#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <ctime>
/*
int gcd(int a,int b)
{
return ! b ? a : gcd(b,a % b);
}
struct data
{
int val;
int pos;
int ranks;
}p[2005];
typedef struct
{
double x,y;
}Point;
bool cmp1(const data &a,const data &b)
{
if(a.val == b.val)
return a.pos < b.pos;
return a.val < b.val;
}
bool cmp2(const data &a,const data &b)
{
return a.val > b.val;
}
bool cmp3(const data &a,const data &b)
{
return a.pos < b.pos;
}
const double ERR = 0.0001;
bool feq (double a, double b)
{
return fabs(a-b) < ERR;
}
double fgcd(double a, double b)
{
if (feq(a, 0))
return b;
if (feq(b, 0))
return a;
return fgcd(b, fmod(a, b));
}
double dist(double x0, double x1, double y0, double y1)
{
return sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
}
*/
#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9 + 7;
using namespace std;
LL m1,m2,b1,b2;
LL x,y;
LL Exgcd(LL a,LL b)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
LL d = Exgcd(b,a % b);
LL p = x;
x = y;
y = p - a / b * y;
return d;
}
int main()
{
//ios_base::sync_with_stdio(false); cin.tie(0);
//freopen("int.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
bool flag = false;
scanf("%lld %lld",&m1,&b1);
b1 %= m1;
for(int i = 1;i < T;i++)
{
scanf("%lld %lld",&m2,&b2);
if(flag)
continue;
LL r = b2 - b1;
LL d = Exgcd(m1,m2);
if(r % d != 0)
{
flag = true;
continue;
}
LL t = m2 / d;
x = ( (r / d * x) % t + t) % t;
b1 = m1 * x + b1;
m1 = m1 / d * m2;
}
printf("%lld\n",flag ? -1 : b1);
return 0;
}
D:n个数,开始时全为1,每次使得其中k个取反(0变1,1变0),问能否通过有限次操作使得这n个数全变为0,问最少次数是多少,n,k都在1e9量级。
这道题的原形其实在小学或者初中数学竞赛中都可以见到,需要讨论n和k 奇偶性以及比例关系。
具体的讨论我就不再多说,只需在讨论前加一个特判,如果n%k == 0,输出n / k。
//#include <bits/stdc++.h>
//#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <ctime>
/*
int gcd(int a,int b)
{
return ! b ? a : gcd(b,a % b);
}
struct data
{
int val;
int pos;
int ranks;
}p[2005];
typedef struct
{
double x,y;
}Point;
bool cmp1(const data &a,const data &b)
{
if(a.val == b.val)
return a.pos < b.pos;
return a.val < b.val;
}
bool cmp2(const data &a,const data &b)
{
return a.val > b.val;
}
bool cmp3(const data &a,const data &b)
{
return a.pos < b.pos;
}
const double ERR = 0.0001;
bool feq (double a, double b)
{
return fabs(a-b) < ERR;
}
double fgcd(double a, double b)
{
if (feq(a, 0))
return b;
if (feq(b, 0))
return a;
return fgcd(b, fmod(a, b));
}
double dist(double x0, double x1, double y0, double y1)
{
return sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
}
*/
#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9;
using namespace std;
int main()
{
//ios_base::sync_with_stdio(false); cin.tie(0);
//freopen("int.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,k;
scanf("%d %d",&n,&k);
LL ans = -1;
if(n % k == 0)
ans = n / k;
else if( (n & 1) && (k & 1) )
{
ans = ceil(n * 1.0 / k);
if( (ans & 1) == 0 )
ans++;
}
else if( (n & 1) == 0)
{
if(k & 1)
{
if(k > n / 2 && k <= n - 1)
{
ans = ceil(n * 1.0 / ( n - k ) );
if(ans & 1)
ans++;
}
else if(k <= n / 2)
{
ans = ceil(n * 1.0 / k);
if(ans & 1)
ans++;
}
}
else
{
if(k > n / 2 && k < n - 1)
ans = 3;
else if(k <= n / 2)
ans = ceil(n * 1.0 / k);
}
}
printf("%lld\n",ans);
return 0;
}
E:给出一个矩阵区域,在区域内给出n个圆,随机选择一个点,问你这个点在这n个圆的内部的圆的数量的平方的期望值是多少。可以化简成为这样一道题目,首先你会求出两个圆的相交面积,然后n方的枚举即可,把这所有的面积加起来就是答案
//#include <bits/stdc++.h>
//#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <ctime>
/*
int gcd(int a,int b)
{
return ! b ? a : gcd(b,a % b);
}
struct data
{
int val;
int pos;
int ranks;
}p[2005];
typedef struct
{
double x,y;
}Point;
bool cmp1(const data &a,const data &b)
{
if(a.val == b.val)
return a.pos < b.pos;
return a.val < b.val;
}
bool cmp2(const data &a,const data &b)
{
return a.val > b.val;
}
bool cmp3(const data &a,const data &b)
{
return a.pos < b.pos;
}
const double ERR = 0.0001;
bool feq (double a, double b)
{
return fabs(a-b) < ERR;
}
double fgcd(double a, double b)
{
if (feq(a, 0))
return b;
if (feq(b, 0))
return a;
return fgcd(b, fmod(a, b));
}
double dist(double x0, double x1, double y0, double y1)
{
return sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
}
*/
#define INF 0x3f3f3f3f
#define eps 1e-6
#define esp 1e-8
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9;
using namespace std;
struct Circle{
double x,y;
double r;
}c[1005];
double calArea(Circle c1, Circle c2)
{
double d;
double s,s1,s2,s3,angle1,angle2,temp;
d=sqrt((c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y));
if(d>=(c1.r+c2.r))//两圆相离
return 0;
if((c1.r-c2.r)>=d)//两圆内含,c1大
return acos(-1.0)*c2.r*c2.r;
if((c2.r-c1.r)>=d)//两圆内含,c2大
return acos(-1.0)*c1.r*c1.r;
angle1=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
angle2=acos((c2.r*c2.r+d*d-c1.r*c1.r)/(2*c2.r*d));
s1=angle1*c1.r*c1.r;s2=angle2*c2.r*c2.r;
s3=c1.r*d*sin(angle1);
s=s1+s2-s3;
return s;
}
int main()
{
//ios_base::sync_with_stdio(false); cin.tie(0);
//freopen("int.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
scanf("%d",&n);
int a,b;
scanf("%d %d",&a,&b);
for(int i = 0;i < n;i++)
scanf("%lf %lf %lf",&c[i].x,&c[i].y,&c[i].r);
double ans = 0;
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
ans += calArea(c[i],c[j]);
printf("%.3f\n",ans / a / b);
return 0;
}
F:用到O(n)筛素数的方法,每个数字都被它的最小素因子筛,可递推
在筛的同时,对于每个数字,维护3个值
1)最终的答案
2)最后被筛的素因子(即最小素因子)
3)被最小素因子筛了几次(即当前最小素因子的次数)
若i%prime[j]==0,说明i已经有素因子prime[j]了,转移时最小素因子的次数++即可
若i%prime[j]!=0,则将当前的最小素因子-次数统计到答案,并更新新的最小素因子,令次数为1
最后求和得到答案
//#include <bits/stdc++.h>
//#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <ctime>
/*
int gcd(int a,int b)
{
return ! b ? a : gcd(b,a % b);
}
struct data
{
int val;
int pos;
int ranks;
}p[2005];
typedef struct
{
double x,y;
}Point;
bool cmp1(const data &a,const data &b)
{
if(a.val == b.val)
return a.pos < b.pos;
return a.val < b.val;
}
bool cmp2(const data &a,const data &b)
{
return a.val > b.val;
}
bool cmp3(const data &a,const data &b)
{
return a.pos < b.pos;
}
const double ERR = 0.0001;
bool feq (double a, double b)
{
return fabs(a-b) < ERR;
}
double fgcd(double a, double b)
{
if (feq(a, 0))
return b;
if (feq(b, 0))
return a;
return fgcd(b, fmod(a, b));
}
double dist(double x0, double x1, double y0, double y1)
{
return sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
}
*/
#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9;
using namespace std;
const int MAX = 1e7 + 5;
bool isnotprime[MAX];
int pre[MAX],p[MAX],ans[MAX],times[MAX];
LL calc(int a,int b)
{
LL r;
if(b == 1)
r = a;
else if(b < 10)
r = 10 * a + b;
else
r = 100 * a + b;
return r;
}
int main()
{
//ios_base::sync_with_stdio(false); cin.tie(0);
//freopen("int.txt","r",stdin);
//freopen("out.txt","w",stdout);
memset(isnotprime,0,sizeof(isnotprime));
LL sum = 1;
int cnt = 0;
int n;
scanf("%d",&n);
for(int i = 2;i <= n;i++){
if(!isnotprime[i])
p[cnt++] = i,ans[i] = 1,pre[i] = i,times[i] = 1;
for(int j = 0;j < cnt && i * p[j] <= n;j++){
isnotprime[i * p[j]] = 1;
pre[i * p[j]] = p[j];
if(i % p[j] != 0){
ans[i * p[j]] = ans[i] * calc(pre[i],times[i]);
times[i * p[j]] = 1;
}
else{
ans[i * p[j]] = ans[i];
times[i * p[j]] = times[i] + 1;
break;
}
}
sum += ans[i] * calc(pre[i],times[i]);
}
printf("%lld\n",sum);
return 0;
}
G:找出n维空间上的n+1个点,使得他们两两之间的距离为1,输出点的坐标
直接强行构造n维单位坐标基,然后再构造第n+1个向量,使得题意满足即可
n维找n个点满足题目的条件是非常容易的
如n=3, (d,0,0) (0,d,0) (0,0,d),d=sqrt(2)/2
根据对称性,剩下的点设为(x,x,x),解方程
//#include <bits/stdc++.h>
//#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <ctime>
/*
int gcd(int a,int b)
{
return ! b ? a : gcd(b,a % b);
}
struct data
{
int val;
int pos;
int ranks;
}p[2005];
typedef struct
{
double x,y;
}Point;
bool cmp1(const data &a,const data &b)
{
if(a.val == b.val)
return a.pos < b.pos;
return a.val < b.val;
}
bool cmp2(const data &a,const data &b)
{
return a.val > b.val;
}
bool cmp3(const data &a,const data &b)
{
return a.pos < b.pos;
}
const double ERR = 0.0001;
bool feq (double a, double b)
{
return fabs(a-b) < ERR;
}
double fgcd(double a, double b)
{
if (feq(a, 0))
return b;
if (feq(b, 0))
return a;
return fgcd(b, fmod(a, b));
}
double dist(double x0, double x1, double y0, double y1)
{
return sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
}
*/
#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9;
using namespace std;
double ans[105][105];
int main()
{
//ios_base::sync_with_stdio(false); cin.tie(0);
//freopen("int.txt","r",stdin);
//freopen("out.txt","w",stdout);
memset(ans,0,sizeof(ans));
int N;
scanf("%d",&N);
double d = sqrt(1.0 / 2);
for(int i = 0;i < N;i++)
ans[i][i] = d;
for(int i = 0;i < N;i++)
ans[N][i] = (sqrt(N / 2.0 + 0.5) + d) / N;
for(int i = 0;i <= N;i++){
for(int j = 0;j < N - 1;j++)
printf("%.12f ",ans[i][j]);
printf("%.12f\n",ans[i][N - 1]);
}
return 0;
}
H:在3维空间里走N步,从原点开始走,问你最多能到过几个点,输出期望值*6^N % 1e9+7
I:求无限迭代后的f(x)在模P意义下的答案
J:求两个凸包之间的最短距离,旋转卡壳的应用网上直接找了个版
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
const double eps = 1e-8;
int sgn(double x)
{
if(fabs(x) < eps)return 0;
if(x < 0)return -1;
else return 1;
}
struct Point
{
double x,y;
Point(double _x = 0.0,double _y = 0.0)
{
x = _x;
y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x, y - b.y);
}
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
void input()
{
scanf("%lf%lf",&x,&y);
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s;
e = _e;
}
};
double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
}
Point NearestPointToLineSeg(Point P,Line L)
{
Point result;
double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));
if(t >= 0 && t <= 1)
{
result.x = L.s.x + (L.e.x - L.s.x)*t;
result.y = L.s.y + (L.e.y - L.s.y)*t;
}
else
{
if(dist(P,L.s) < dist(P,L.e))
result = L.s;
else result = L.e;
}
return result;
}
/*
* 求凸包,Graham算法
* 点的编号0~n-1
* 返回凸包结果Stack[0~top-1]为凸包的编号
*/
const int MAXN = 10010;
Point list[MAXN];
int Stack[MAXN],top;
//相对于list[0]的极角排序
bool _cmp(Point p1,Point p2)
{
double tmp = (p1-list[0])^(p2-list[0]);
if(sgn(tmp) > 0)return true;
else if(sgn(tmp) == 0 && sgn(dist(p1,list[0]) - dist(p2,list[0])) <= 0)
return true;
else return false;
}
void Graham(int n)
{
Point p0;
int k = 0;
p0 = list[0];
//找最下边的一个点
for(int i = 1;i < n;i++)
{
if( (p0.y > list[i].y) || (p0.y == list[i].y && p0.x > list[i].x) )
{
p0 = list[i];
k = i;
}
}
swap(list[k],list[0]);
sort(list+1,list+n,_cmp);
if(n == 1)
{
top = 1;
Stack[0] = 0;
return;
}
if(n == 2)
{
top = 2;
Stack[0] = 0;
Stack[1] = 1;
return ;
}
Stack[0] = 0;
Stack[1] = 1;
top = 2;
for(int i = 2;i < n;i++)
{
while(top > 1 && sgn((list[Stack[top-1]]-list[Stack[top-2]])^(list[i]-list[Stack[top-2]])) <= 0)
top--;
Stack[top++] = i;
}
}
//点p0到线段p1p2的距离
double pointtoseg(Point p0,Point p1,Point p2)
{
return dist(p0,NearestPointToLineSeg(p0,Line(p1,p2)));
}
//平行线段p0p1和p2p3的距离
double dispallseg(Point p0,Point p1,Point p2,Point p3)
{
double ans1 = min(pointtoseg(p0,p2,p3),pointtoseg(p1,p2,p3));
double ans2 = min(pointtoseg(p2,p0,p1),pointtoseg(p3,p0,p1));
return min(ans1,ans2);
}
//得到向量a1a2和b1b2的位置关系
double Get_angle(Point a1,Point a2,Point b1,Point b2)
{
Point t = b1 - ( b2 - a1 );
return (a2-a1)^(t-a1);
}
//旋转卡壳,求两个凸包的最小距离
double rotating_calipers(Point p[],int np,Point q[],int nq)
{
int sp = 0, sq = 0;
for(int i = 0;i < np;i++)
if(sgn(p[i].y - p[sp].y) < 0)
sp = i;
for(int i = 0;i < nq;i++)
if(sgn(q[i].y - q[sq].y) > 0)
sq = i;
double tmp;
double ans = 1e99;
for(int i = 0;i < np;i++)
{
while(sgn(tmp = Get_angle(p[sp],p[(sp+1)%np],q[sq],q[(sq+1)%nq])) < 0 )
sq = (sq + 1)%nq;
if(sgn(tmp) == 0)
ans = min(ans,dispallseg(p[sp],p[(sp+1)%np],q[sq],q[(sq+1)%nq]));
else ans = min(ans,pointtoseg(q[sq],p[sp],p[(sp+1)%np]));
sp = (sp+1)%np;
}
return ans;
}
double solve(Point p[],int n,Point q[],int m)
{
return min(rotating_calipers(p,n,q,m),rotating_calipers(q,m,p,n));
}
Point p[MAXN],q[MAXN];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 0;i < n;i++)
list[i].input();
Graham(n);
n = top;
for(int i = 0;i < n;i++)
p[i] = list[Stack[i]];
for(int i = 0;i < m;i++)
list[i].input();
Graham(m);
m = top;
for(int i = 0;i < m;i++)
q[i] = list[Stack[i]];
printf("%.5lf\n",solve(p,n,q,m));
return 0;
}