T1
题意
已知三个数n,k,t,人数i在n+k按以下规律变化:
t·=1-k:编号为t的人起立
t·=k-n:编号为t的人起立,编号为t-k的人坐下
t·=n-(n+k):编号为t-k的人坐下
求在给定的时间点t时站着的人数
题解
简单的if判断题
输入后进行判断:
t<k:i=t
k<t<n:i=k
n<t<n+k:i=n+k-t
T2
题意
已知三个点坐标,问有没有一个点可以使a旋转后到b的位置,而b到c的位置
题解
成立条件:三点不共线且a-b,b-c距离相同
注意求距离时不需要开方:可能因为精度问题而GG(前几次就这么错的)
斜率判断较易
#include<bits/stdc++.h>
using namespace std;
long long a[2],b[2],c[2];
long long juli(long long a,long long b,long long c,long long d)
{
return (a-c)*(a-c)+(b-d)*(b-d);
}
bool xielv(long long a,long long b,long long c,long long d,long long e,long long f)
{
if((d-b)*(e-c)==(f-d)*(c-a)) return 0;
return 1;
}
int main()
{
scanf("%lld%lld%lld%lld%lld%lld",&a[0],&a[1],&b[0],&b[1],&c[0],&c[1]);
if(juli(a[0],a[1],b[0],b[1])==juli(b[0],b[1],c[0],c[1])&&xielv(a[0],a[1],b[0],b[1],c[0],c[1])) printf("Yes");
else printf("No");
return 0;
}
T3
题意
已知n个五维点,问有几个点满足使其他任意两个点与此点的夹角均为钝角
题解
首先,要满足条件至多有11个点(每个维度两个+本身一个)
题目给的公式可以简化
(友情链接http://blog.csdn.net/qq_40065805到大佬博客,因为解释不出)
using namespace std;
int n,a[1010],b[1010],c[1010],d[1010],e[1010],i,ans[1010]= {0},j,o,u=0,p=1;
int angle(int x,int y,int z)
{
return (a[x]-a[y])*(a[x]-a[z])+(b[x]-b[y])*(b[x]-b[z])+(c[x]-c[y])*(c[x]-c[z])+(d[x]-d[y])*(d[x]-d[z])+(e[x]-e[y])*(e[x]-e[z]);
}
int main()
{
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d%d%d%d%d",&a[i],&b[i],&c[i],&d[i],&e[i]);
}
if(n>11)
{
printf("0");
}
else
{
for(i=1; i<=n; i++)
{
p=1;
for(j=1; j<n; j++)
{
if(j==i)continue;
for(o=j+1; o<=n; o++)
{
if(o==i)continue;
if(angle(i,j,o)>0)
{
p=0;
break;
}
}
if(p==0)break;
}
if(p==1)
{
ans[0]++;
u++;
ans[u]=i;
}
}
for(i=0; i<=u; i++)printf("%d\n",ans[i]);
}
return 0;
}
T4
题意
已知n个骰子和目标点数及每个骰子能达到的最大值d[i],问这n个骰子不能掷出的值的个数
题解
设某一个骰子扔的点数为x,那么0<x<=d[i]设其他骰子扔到的总点数为y,则y+x=a,且y>=n-1(在其他的所有骰子都扔1),且y<=sum-num[i](在其他所有骰子都扔最大值)
#include<bits/stdc++.h>
using namespace std;
long long n,k,d[200010],r[200010],i,sum=0;
int main()
{
scanf("%lld%lld",&n,&k);
for(i=1;i<=n;i++)
{
scanf("%lld",&d[i]);
sum+=d[i];
}
for(i=1;i<=n;i++)
{
r[i]=min((k+(long long)1-n),d[i])-max((k+d[i]-sum),(long long)1)+1;
r[i]=d[i]-r[i];
}
for(i=1;i<=n;i++)
{
printf("%lld ",r[i]);
}
return 0;
}
T5
题意
n个数的a序列,问满足:
b[i]<=a[i]
lcm(b)=max(b)
的序列b的个数
题解
枚举最大数,然后找出它所有因数b1…….bk,任意选取数组p中的一些数,且这些数的最大LCM就是枚举的这个最大数,此时若bi<=aj<=bi+1则前i个数可以放在j这个位置,即j这个位置有cj种选择,则有总数c1*c2*……*cj
#include<bits/stdc++.h>
using namespace std;
const long long MOD=1000000007;
long long j,n,a[100010],b[100010],ans=0,i,cnt,t,s,k;
long long gcd(long a,long b)
{
if(a%b==0) return b;
else return gcd(b,a%b);
}
long long lcm(long long a,long long b)
{
return a*b/gcd(a,b);
}
void fact(long long n)
{
long long t=sqrt(n+0.5),i;
cnt=0;
for(i=1; i<=t; i++)
{
if(n%i==0)b[++cnt]=i;
}
i=cnt;
cnt*=2;
if(t*t==n)cnt--,i--;
for(; i; i--)
{
b[cnt-i+1]=n/b[i];
}
}
long long pwmd(long long a,long long b)
{
long long ret=1;
while(b)
{
if(b&1)ret=ret*a%MOD;
b>>=1;
a=a*a%MOD;
}
return ret;
}
int main()
{
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
for(i=1; i<=a[n]; i++)
{
fact(i);
t=0;
s=1;
for(j=2; j<=cnt; j++)
{
k=lower_bound(a+t+1,a+n+1,b[j])-a-1;
s=s*pwmd(j-1,k-t)%MOD;
t=k;
}
s=s*(pwmd(cnt,n-t)+MOD-pwmd(cnt-1,n-t))%MOD;
ans=(ans+s)%MOD;
}
printf("%lld",ans);
return 0;
}
总结
这次比赛做E题扒了两个函数的模板照说明书贴上去,强行A掉了。。。还有C题的向量没看懂题意,日后要追进学习。
以后会向其他同学请教学习,先把这些模板完全理解并能自己想到,使用,打出。此外还跟进其他实用算法的学习,理解dfs和bfs的用法,循序渐进(不会用模板速成了。。)