之前题目比较水,今天的还可以。
【A 不凡的大夫】
方法一:答案是log8(n!),解决方案是预处理,将需要的答案记录下来以免超内存;
方法二:用公式,斯特林公式:
【B 一个小问题】
题解:线性同余方程组,一看就不是中国剩余定理,当心。
【C 守护白起】
题解:polya。。。。。比赛的时候忘记加逆元。。。mmp,然后WA了,后面来不及了。
【D 小牛vs小客】
题解:对称博弈,做过不久,先考虑特殊情况,再考虑对称性。
【E 进击吧!阶乘】
题解:高精度裸题,py可以直接码。
【F 小牛再战】
题解:博弈,好像和奇偶有关。
【G 大水题】
题解:简单容斥定理。
【H 向左走】
一眼不会题。。。。。。。
【I 三角形】
题解:面积可以用海伦公式或者向量法,(自己习惯向量法);GCD求线段上整点;皮克定理求内部整点。
--------------------------------------------------分界线--------------------------------------------------------------
对于一个数学不好的人(队伍)来说,这次是敲响了警钟。!
上面的东西会尽快补齐的。
【A】预处理:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
int N;
struct query{
int id,num;
bool friend operator<(const query&A,const query&B)
{return A.num<B.num;}
}q[1000010];
int ans[1000010];
int main(){
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%d",&q[i].num),q[i].id=i,q[i].num;
sort(q+1,q+1+N);
int now=1,cnt=1;
double temp=3;
while(q[now].num==0)
ans[q[now++].id]=1;
for(int i=1;i<=q[N].num;i++){
temp=temp+log2(1.0*i);
while(q[now].num==i)
ans[q[now++].id]=temp/3;
}
for(int i=1;i<=N;i++)
printf("%d\n",ans[i]);
return 0;
}
斯特林:
【B】求解线性同余方程组


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#define ll long long
using namespace std;
void Ex_gcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if(b==0){ d=a; x=1; y=0; return ;}
Ex_gcd(b,a%b,d,y,x); y-=a/b*x;
}
int main()
{
ll c1,c2,c,a,b,d,x,y,n;
while(~scanf("%lld",&n)){
bool Flag=false;
scanf("%lld%lld",&a,&c1);
for(int i=2;i<=n;i++) {
scanf("%lld%lld",&b,&c2);
if(Flag) continue; c=c2-c1;
Ex_gcd(a,b,d,x,y);
if(c%d!=0) { printf("-1\n"); Flag=true;}
x=((c/d*x)%(b/d)+b/d)%(b/d);//最小正单元
c1=a*x+c1;a=a*b/d;
}
if(!Flag) printf("%lld\n",c1);
//yes
} return 0;
}
【C】polya(记住加逆元!!!)


#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
const int Mod=1000000007;
#define ll long long
ll gcd(ll a,ll b) { if(b==0) return a; return gcd(b,a%b); }
ll qpow(ll a,ll x)
{
ll res=1;a%=Mod;
while(x){
if(x&1LL) res=res*a%Mod;
x>>=1LL;
a=a*a%Mod;
} return res;
}
int main()
{
ll T,ans,n,m,i,Case=0;
scanf("%lld",&T); while(T--){
scanf("%lld%lld",&m,&n);
ans=0;
for(i=0;i<n;i++) ans=(ans+qpow(m,gcd(n,i)))%Mod;
if(n&1) ans=(ans+n*qpow(m,n/2+1))%Mod;
else {
ans=(ans+n/2*qpow(m,n/2))%Mod;
ans=(ans+n/2*qpow(m,n/2+1))%Mod;
}
ans=ans%Mod*qpow(2*n,Mod-2)%Mod;
printf("Case #%lld: %lld\n",++Case,ans);
}
return 0;
}
【D】博弈:


#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
int T,n,k=2,cas=1;
while(~scanf("%d",&n))
{
if(n%2==1&&k==1) cout<<"XiaoNiu"<<endl;
else if(k>=n) cout<<"XiaoNiu"<<endl;
else cout<<"XiaoKe"<<endl;
}
return 0;
}
【E】高精度


#include<stdio.h>
int a[10005];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int index,temp,i,j;
a[0]=1;
index=0;
for(i=1;i<=n;i++)
{
temp=0;
for(j=0;j<=index;j++)
{
a[j]=a[j]*i+temp;
temp=a[j]/10000;
a[j]%=10000;
}
if(temp>0)
{
a[++index]=temp;
}
}
printf("%d",a[index]);
for(i=index-1;i>=0;i--)
{
if(a[i]>=1000)
printf("%d",a[i]);
else if(a[i]>=100)
printf("0%d",a[i]);
else if(a[i]>=10)
printf("00%d",a[i]);
else
printf("000%d",a[i]);
}
printf("\n");
}
return 0;
}
【F】数据有问题。


#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e3+10;
int vis[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n==0)
break;
int t;
for(int i=0;i<n;i++)
{
scanf("%d",&t);
vis[t]++;
}
int flag=0;
for(int i=0;i<101;i++)
{
if(vis[i]%2==1)
{
flag=1;
break;
}
}
if(flag)
printf("Win\n");
else
printf("Lose\n");
memset(vis,0,sizeof(vis));
}
return 0;
}
【G】容斥定理


#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
long long qpow(int a,int x)
{
long long res=1;
while(x){
if(x&1) res*=a;
a=a*a;
x>>=1;
} return res;
}
int main()
{
long long n,ans,tmp;
int a,b,c,d,i,j,k,x;
while(~scanf("%lld",&n)){
ans=0;
ans+=n/2;
ans+=n/5;
ans+=n/11;
ans+=n/13;
ans-=n/(2*5);
ans-=n/(2*11);
ans-=n/(2*13);
ans-=n/(5*11);
ans-=n/(5*13);
ans-=n/(11*13);
ans+=n/(2*5*11);
ans+=n/(2*11*13);
ans+=n/(5*11*13);
ans+=n/(2*5*13);
ans-=n/(2*5*11*13);
printf("%lld\n",n-ans);
//yes
} return 0;
}
【H】不会
【I】皮克+GCD


#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
ll x[4],y[4],ans[4];
double S;
ll gcd(ll a,ll b)
{
return b== 0 ? a : gcd(b,a%b);
}
void getS()
{
ll x1=x[2]-x[1];
ll y1=y[2]-y[1];
ll x2=x[3]-x[1];
ll y2=y[3]-y[1];
S=abs(1.0*x1*y2-x2*y1)/2;
}
void get(int u)
{
int x0,y0;
if(u==1){
x0=abs(x[2]-x[1]);
y0=abs(y[2]-y[1]);
}
if(u==2){
x0=abs(x[3]-x[2]);
y0=abs(y[3]-y[2]);
}
if(u==3){
x0=abs(x[3]-x[1]);
y0=abs(y[3]-y[1]);
}
if(x0==0&&y0==0) ans[u]=1;
ans[u]=gcd(x0,y0)-1;
}
int main()
{
while(~scanf("%lld",&x[1])){
if(x[1]==-1) break;
scanf("%lld%lld%lld%lld%lld",&y[1],&x[2],&y[2],&x[3],&y[3]);
getS();
get(1);
get(2);
get(3);
int tS=S;
ans[0]=S-(ans[1]+ans[2]+ans[3]+3)/2+1;
printf("%.1f %lld %lld %lld %lld\n",S,ans[0],ans[1],ans[2],ans[3]);
}
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/4362312/blog/4227822