T1
题面
题意
球场上有n名观众,从1到N号,他们在0时开始观看比赛。
在1时,第一个观众起立。
在2时,第二个观众起立。
…
在k时,第k个观众起立。
在k + 1时,第一个观众坐下。
在k + 2时,第二个观众坐下。
…
在n时,第n个观众起立和第(n- k)个观众坐下。
输入n,k,t,输出站着的观众数
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,k,t,i;
cin>>n>>k>>t;
if(t<=k)
{
cout<<t;
return 0;
}
if(t>k&&t<=n)
{
cout<<k;
return 0;
}
if(t>n&&t<=n+k)
{
cout<<n+k-t;
return 0;
}
if(t>n+k)
{
cout<<0;
return 0;
}
}
方法
分四类进行讨论:人数增加,再不变(起立与坐下平衡)再减少,最后不变(为0).
T2
题面
题意
输入三个点A,B,C的坐标.
问是否能找到某一个点和某一个角度,我们若将页面围绕这个点旋转这个角度,能使A的新位置和B的旧位置一样,B的新位置和C的旧位置一样。
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long ax,ay,bx,by,cx,cy;
double jl1,jl2;
cin>>ax>>ay>>bx>>by>>cx>>cy;
if((ax-bx)*(by-cy)==(ay-by)*(bx-cx))//判断斜率是否相同以判断是否三点共线
{
cout<<"No";
return 0;
}
//若绕AB中垂线上一点转,必能找到一个角度使新A与B重合
//若三点不共线,则AB与BC的中垂线必有交点
jl1=sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
jl2=sqrt((cx-bx)*(cx-bx)+(cy-by)*(cy-by));
if(jl1==jl2)
{
cout<<"Yes";
return 0;
}//判断距离是否相等来判断能否完成
cout<<"No";
}
T3
题面
题意
输入n,再输入n个五维空间中点的坐标.若以一个点为顶点,将另外任意两点与它相连,构成的夹角均大于等于90度,则为好点
输出好点数,以下几行每行一个整数表示好点序号
代码
#include<bits/stdc++.h>
using namespace std;
/*
6
0 0 0 0 0
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
*/
/*
1
1
*/
//样例
const long long N=1010;
long long an[N],ans=0,a[N],b[N],c[N],d[N],e[N],n,dc[N];
int js(long long p,long long q)
{
long long sum,ji1,ji2,ji3,ji4,ji5;
ji1=a[p]-a[q];
ji2=b[p]-b[q];
ji3=c[p]-c[q];
ji4=d[p]-d[q];
ji5=e[p]-e[q];
sum=ji1*ji1+ji2*ji2+ji3*ji3+ji4*ji4+ji5*ji5;
return sum;
}
//勾股定理(扩展版),计算两点间距离的平方
int jy(long long j,long long b1,long long b2)
{
if(js(j,b1)+js(j,b2)<=js(b1,b2))
return 0;
else return 1;
}
//若角的两夹边的平方和小于等于对边的平方则该角(小于180)为直角或钝角
int main()
{
long long i,j,k,pd,pd2;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[i]>>b[i]>>c[i]>>d[i]>>e[i];
}
if(n<3)
{
cout<<n<<endl;
for(i=1;i<=n;i++)
cout<<i<<endl;
return 0;
}
for(i=1;i<=n;i++)//i表示角的顶点
{
pd=0;
for(j=1;j<=n;j++)
{
if(j!=i)
{
pd2=0;
for(k=j+1;k<=n;k++)//列举端点k,j来判断是否满足所有
{
if(k!=i)
{
if(jy(i,j,k)==1)
{
pd2=1;
break;
}
}
}
if(pd2==1)
{
pd=1;
break;
}
}
}
if(pd==0)
{
ans++;
an[ans]=i;
}
}
cout<<ans<<endl;
for(i=1;i<=ans;i++)
cout<<an[i]<<endl;
}
方法
暴力穷举每一个顶点,并穷举其余两顶点,用勾股定理来判断
T4
题面
题意
有N个骰子 D1,D2….DN。第i个骰子上的数字是从1到i。掷骰子(每一个骰子掷一次)的数字总和为A.
不知道每一个骰子显示什么号码,但知道每个骰子的面数 D1,D2 …..DN,故知道每个骰子有R个数不能显示。
例如,有两个六面骰子的总和是11,那么两个骰子不能显示小于五的值(否则,剩下的骰子必须至少为七,这样是不可能的)。
输入
第一行包含两个整数n, A,(1 ≤ N ≤ 2·105, N ≤ A ≤ S)n为骰子的数量,A为显示点数之和S=D1+D2+…..DN。
第二行包含N个整数 D1,D2……DN(1 ≤ Di ≤ 106.
输出
打印n个整数 B1,B2, …,Bn,其中BI是第i个骰子不能显示的数字个数
代码
#include<bits/stdc++.h>
using namespace std;
long long n,sum,s,a[200001],ans[200001];
int main()
{
long long min,max,i;
cin>>n>>sum;
for(i=1;i<=n;i++)
{
cin>>a[i];
s+=a[i];//记录面数之和方便后续计算
}
for(i=1;i<=n;i++)
{
max=sum-n+1;
min=sum-(s-a[i]);//该骰子能显示的最大值与最小值
// cout<<min<<" "<<max<<" ";
if(1<min)
{
ans[i]=ans[i]+min-1;
}
if(a[i]>max)
{
ans[i]=ans[i]+a[i]-max;
}
// cout<<ans[i]<<" ";
}
for(i=1;i<=n;i++)
cout<<ans[i]<<" ";
}
T5
题面
题意
输入一个整数序列,进行一系列操作使它的最大值恰好为最小公倍数.
操作:可以将序列中任何一个数变为小于等于它的数.
输出操作总数对1000000007取模的结果
方法
通过前缀和来记录一个区间内数的个数,详见代码.
求出最大值,并枚举
每乘一次就对1000000007取一次模
代码
#include<bits/stdc++.h>
#define N 100010
#define ll long long
#define M 1000000007
using namespace std;
ll n,a,cnt[N],sum[N],mx,an,ans;
ll pow(ll u,ll v)
{
ll i,z=1;
while(v!=0)
{
if(v&1)//如果转化为2进制后末位为1
z=z*u%M;//就乘u
u=u*u%M;
v=(v >> 1);//v=v/2,位运算较快
}
return z;
}
//这样写指数函数更快
ll fj(ll u)//该函数将u的因子存在了cnt中,且长度为j
{
ll i,j=0,v;
v=(ll)sqrt(u);
for(i=1;i<=v;i++)//枚举到根号u,若i能整除,则u/i也能
{
if(u%i==0)
{
j++;
cnt[j]=i;
if(i*i!=u)
{
j++;
cnt[j]=u/i;
}
}
}
return j;
}
void js(ll z)
{
ll i,j,len,gs,k;
an=1;
len=fj(z);
sort(cnt+1,cnt+len+1);
for(i=1;i<len;i++)
{
an=(an*pow(i,sum[cnt[i+1]-1]-sum[cnt[i]-1]))%M;
//在第i个因子到第i+1个因子间,每个因子都有i个选择
}
gs=n-sum[cnt[len]-1];
k=(pow(len,gs)+M-pow(len-1,gs))%M;//最大值特判,因为必须有数为最大值
an=(an*k)%M;
ans=(ans+an)%M;
}
int main()
{
ll i,j,p=0;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a;
mx=max(mx,a);
sum[a]++;
}
for(i=1;i<N;i++)
{
sum[i]+=sum[i-1];//用前缀和维护,方便计算
}
for(i=1;i<=mx;i++)//枚举最大值
{
js(i);
}
cout<<ans;
}