政史特长生友谊赛Round1题解

xiaoxiao2021-02-27  168

Problem A 不会排序?对不起,我无可奉告。

Problem B 每个人操作的过程可以这么描述:遇到第一个0之前,将路上所有的1变成0,并将第一个0变成1,不难发现这其实相当于二进制的加一操作。共m次操作则相当于把m转为二进制然后输出末n位。

#include<bits/stdc++.h> using namespace std; typedef long long LL; int a[65]; int main(){ int n; LL m; cin>>n>>m; int t=0; while (t<n){ a[++t]=m%2; m/=2; } for (int i=n;i>=1;i--) printf("%d",a[i]); }

Problem C 首先不难设计出平方级的算法:i枚举n,j枚举t,然后直接累加即可。如果画个图就可以发现,j多次扫描过了同一点,所以可以将i与j的父子关系转为兄弟关系,用单调队优化。

#include<bits/stdc++.h> using namespace std; const int maxn=1000000+5; int m[maxn],t[maxn],q[maxn]; int main(){ int n,x,y; cin>>n>>x>>y; for (int i=1;i<=n;i++) scanf("%d%d",&m[i],&t[i]); int j=1,ans=1; q[m[1]]=1; printf("1"); for (int i=2;i<=n;i++){ if (!q[m[i]]) ans++; q[m[i]]++; while (t[i]-t[j]>y){ q[m[j]]--; if (!q[m[j]]) ans--; j++; } printf(" %d",ans); } }

Problem D 裸的威佐夫博弈。 我们用(ak,bk)(ak ≤ bk , k = 0,1,2,…,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为必败局势。前几个必败局势是:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。可以看出,a0 = b0 = 0,ak是未在前面出现过的最小自然数,而 bk = ak + k。 必败局势有3条神奇的性质: 1、任何自然数都包含在一个且仅有一个必败局势中。 证明:由于ak是未在前面出现过的最小自然数,所以有ak > ak-1 ,而 bk= ak + k > ak-1 + k-1 = bk-1 > ak-1 ,所以性质1成立。 2、任意操作都可以将必败局势改为非必败局势。 证明:若只改变必败局势(ak,bk)的某一个分量,那么另一个分量不可能在其他必败局势中,所以必然是非必败局势。如果使(ak,bk)的两个分量同时减少,则由于其差不变,且不可能是其他必败局势的差,因此也是非必败局势。 3、采用适当的方法,可以将非必败局势变为必败局势。 可以想到,两个人如果都采用正确操作,那么面对非必败局势先拿者必胜;反之则后拿者取胜。 如何判断一个局势是否必败呢?我们有一个公式:ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,…,n 方括号表示取整函数)。 具体做法:对于局势(x , y),判断 x ?= ((y-x)*(sqrt(5)+1)) / 2 向下取整。

#include<iostream> #include<cmath> using namespace std; int main(){ int a,b; cin>>a>>b; if (a<b) swap(a,b); int c=(int)(a-b)*(1+sqrt(5))/2.0; if (c==b) cout<<0; else cout<<1; }
转载请注明原文地址: https://www.6miu.com/read-12602.html

最新回复(0)