比赛地址 http://acm.sdibt.edu.cn/vjudge/contest/view.action?cid=2186#overview
A Islands in the Data Stream
INPUT
4
1 0 0 1 1 2 2 1 1 0 1 2 2 1 1 0
2 0 1 2 3 4 3 2 1 2 3 4 3 2 1 0
3 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
4 0 1 2 3 4 5 6 7 6 5 4 3 2 1 0
output
1 4
2 7
3 7
4 7
题目与之前17级201917级2019春季个人训练赛-2比赛一个题重复
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
const int MAX=1e6+7;
deque <char> dq;
stack <char> s;
int main()
{
ll T,i,j,k,a[1010],ans=0,e;
cin>>T;
while(T--)
{
cin>>e;
ans=0;
memset(a,0,sizeof(a));
for(i=1;i<=15;i++)
cin>>a[i];
for(i=1;i<=13;i++)
{
for(j=2;j<=15-i;j++)
{
ll minn=MAX;
for(k=j;k<=j+i-1;k++)
{
if(a[k]<minn)
minn=a[k];
}
if(a[j-1]<minn&&a[j+i]<minn)
ans++;
}
}
cout<<e<<" "<<ans<<endl;
}
return 0;
}
B Von Neumann's Fly
Input
5
1 250 10 15 20
2 10.7 3.5 4.7 5.5
3 523.7 15.3 20.7 33.3
4 1000 30 30 50
5 500 15 15 25
output
1 200.00
2 7.18
3 484.42
4 833.33
5 416.67
题意:每组给出四个数,D(甲乙两地路程总距离),A(A的速度),B(B的速度),F(飞机的速度)。让A从甲地出发到乙地,B从乙地出发到甲地,飞机从A出发,当遇到A或B时需要回头,问当AB相遇时,飞机走的总路程。
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
const int MAX=1e6+7;
deque <char> dq;
stack <char> s;
int main()
{
ll T,i,j,k,a[1010],ans=0,e;
scanf("%lld",&T);
while(T--)
{
//cin>>e;
scanf("%lld",&e);
double D,A,B,F;
scanf("%lf%lf%lf%lf",&D,&A,&B,&F);
double p=(double)D/(A+B);
double ans=F*p;
printf("%lld %.2lf\n",e,ans);
//cout<<e<<" "<<ans<<endl;
}
return 0;
}
D Pisano Periods
Input
5
1 4
2 5
3 11
4 123456
5 987654
output
1 6
2 20
3 10
4 15456
5 332808
题意:每组样例的第2个数m,用斐波那契数组对它求余,求周期的长度。
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
const int MAX=1e6+7;
deque <char> dq;
stack <char> s;
ll f[1000001]= {0};
int main()
{
ll T,i,j,k,m,ans=0,e;
cin>>T;
while(T--)
{
cin>>e>>m;
ll p=0,a=0,b=0;
memset(f,0,sizeof(0));
f[1]=1;
f[2]=1;
for(i=3; i<=1000000; i++)
{
f[i]=(f[i-1]+f[i-2])%m;
if(f[i]==1&&f[i-1]==1&&f[i-2]==0)
{
cout<<e<<" "<<i-2<<endl;
break;
}
}
}
return 0;
}
以上是比赛过程中做出来的。
E Deranged Exams
Sample Input
4
1 4 1
2 7 3
3 10 5
4 17 17
Sample Output
1 18
2 3216
3 2170680
4 130850092279664
1)首先,至少前k个匹配错,做起来很麻烦,我们找它的对立事件:至多前k个对。
2)假设n=7, k=3:
当计算前三个只有一个正确时,我们得到的情况数为 C(3,1)*A(6,6) ,即从前3个中选一个认为对,其他6个乱排。我们发现,这重复计算了有2个正确和有3个正确的情况,于是我们减去有2个正确的情况数C(3,2)*A(5,5),我们又发现这样多减掉了三个正确的情况,于是再加回来C(3,3)*A(4,4)。最终的到情况总数为 C(3,1)*A(6,6) - C(3,2)*A(5,5) + C(3,3)*A(4,4)。
以此类推,我们就得出了计算方式:取奇数时加,偶数时减,最终求出至多前k个对的情况数。
3)所求 = 所有情况数 - 至多前k个对的情况数 ,即 A(n,n) - sum。
4)下面的代码中,我用 a [ i ] 表示 i 的阶乘,先计算出了a 数组,因为1 ≤ N ≤ 17,用的时候直接取,不必重复计算,省时省力。
a [ k ] / ( a [ k - i ] * a [ i ] ) 就是C(k,i),排列组合公式。emmm... 记得开long long...
以上原文地址 https://blog.csdn.net/lxt_lucia/article/details/88534944 欢迎浏览~
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
const int MAX=1e6+7;
ll a[25];
int main()
{
ll T,i,j,k,n,ans=0,e;
cin>>T;
memset(a,0,sizeof(a));
a[1]=1;
a[0]=1;
for(i=2;i<=20;i++)
a[i]=a[i-1]*i;
while(T--)
{
cin>>e>>n>>k;
ans=0;
for(i=1;i<=k;i++)
{
if(i%2!=0)
ans+=(a[k]/(a[k-i]*a[i]))*a[n-i];
else
ans-=(a[k]/(a[k-i]*a[i]))*a[n-i];
}
cout<<e<<" "<<a[n]-ans<<endl;
}
return 0;
}
C - Strahler Order
Sample Input
1
1 7 8
1 3
2 3
6 4
3 4
3 5
6 7
5 7
4 7
Sample Output
1 3
题意 :有n个点,m条边,将入度为0的标记为1,然后如果有2个及以上的点是该点的前驱,那么这个点的等级为i+1,如果只有一个等级为i的是该点的前驱,这个点的等级就是i,求n个点中等级最大的点。
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
const int MAX=1e6+7;
deque <ll> dq;
ll a[1010][1010];
ll du[1010]={0};
ll dj[1010]={0};
ll vis[1010]={0};
int tp(ll n)
{
ll i;
while(!dq.empty())
{
ll t=dq.front();
dq.pop_front();
if(vis[t]==1)//说明该点有两个或两个以上度数一样的前驱
dj[t]++;
for(i=1;i<=n;i++)//遍历找该点的后继
{
if(a[t][i]==1)
{
du[i]--;//符合时,每次将入度减一,最后入度为0时将该点放入队列中
if(dj[i]==dj[t])//该点与它的前驱等级相等,只标记vis数组
{
vis[i]=1;
}
if(dj[i]<dj[t])//该点比前驱等级小,vis清零,等级变为前驱的等级
{
vis[i]=0;//不清零的话就不满足下面的例子
dj[i]=dj[t];
}
//举个例子,当一个点刚被遍历到时,它前驱的等级有2 2 3,所以会先执行第2个if.
//然后执行第一个if,在执行第2个if,所以vis的作用就是标记它是否有两个及
//以上前驱相同的点,等当从队列里取出的时候,只等级加一次。
if(du[i]==0)
dq.push_back(i);
}
}
}
ll ans=-1;//找最大的等级
for(i=1;i<=n;i++)
{
if(dj[i]>=ans)
ans=dj[i];
}
return ans;
}
int main()
{
ll T,i,j,k,n,m,ans=0,e,x,y;
cin>>T;
while(T--)
{
memset(a,0,sizeof(a));
memset(du,0,sizeof(du));//点的入度
memset(dj,0,sizeof(dj));//点的等级
memset(vis,0,sizeof(vis));
while(!dq.empty())
{
dq.pop_front();
}
cin>>e>>n>>m;
for(i=0;i<m;i++)
{
cin>>x>>y;
a[x][y]=1;
du[y]++;
}
for(i=1;i<=n;i++)
{
if(du[i]==0)//先将入度为0的点放到队列中,并且将等级赋为1
{
dq.push_back(i);
dj[i]=1;
}
}
ll ans=tp(n);
cout<<e<<" "<<ans<<endl;
}
return 0;
}