A - Chat Group
水题,意思是求 ∑ i = k n ( n k ) \sum_{i=k}^{n} {n \choose k} ∑i=kn(kn) ,n<1e9,k<1e5。要取模
发现直接按照n来求不行,如果按照k来求的话,我们可以反着做。
发现从 ( n k ) n \choose k (kn)到 ( n k + 1 ) n \choose k+1 (k+1n) 相当于乘以一个分子n-k,除以一个分母k。这个很简单,推一下就行。
#include
#define ll long long
using namespace std;
const ll mod = 1e9 + 7;
ll pow_mod(ll a,ll n,ll mod)
{
ll res = 1;
a %= mod;
while(n)
{
if(n & 1) res = res * a% mod;
a = a *a % mod;
n >>= 1;
}
return res;
}
int main()
{
int ca,cat = 1;
cin>>ca;
while(ca--)
{
ll n,k;
cin>>n>>k;
ll num = n;
ll ans = pow_mod(2,n,mod)-1;
for(int i = 1;i<k;i++)
{
ans = (ans - num + mod) % mod;
num = (num*(n - i)%mod)*pow_mod(i+1,mod-2,mod)%mod;
}
cout<<"Case #"<<cat++<<": "<<ans<<endl;
}
}
C - Traffic Light
阅读理解题,也就是说我可以让所有的灯都变成绿的,但是为了给自己找麻烦,需要等一个最长的红灯。
求个max没了,阅读理解题真的没意思
#include
#define ll long long
using namespace std;
const int MAXN = 2e5 + 5;
int a[MAXN],b[MAXN];
int s[MAXN];
ll sum[MAXN];
int main()
{
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
int n;
scanf("%d",&n);
for(int i = 1;i<=n+1;i++) scanf("%d",&s[i]),sum[i]=sum[i-1]+s[i];
for(int i = 1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
ll ans = 0;
for(int i = 1;i<=n;i++)
{
ans = max(ans,1LL*b[i]);
}
printf("Case #%d: %I64d.000000\n",cat++,sum[n+1] + ans);
}
}
J - Straight Master
判断一个序列能不能用3,4,5长度的线段,完全覆盖。
找肯定是GG,由线段覆盖我们可以想到差分,差分之后,我们会发现:
如果一个点的值是正的,那么这个点一定有若干个线段是起始点
如果一个点的值是负的,那么这个点一定有若干个线段在这里结尾
顺着这个方向思考,我们会发现一个正数点右边一定有足够的负数点,所以我们直接判断一下这个端点+3位置的点,实际上是长度为3的结束点,假设这里没有长度为3的线段,那么就先保存起来。最后一定会消除,如果不能消除,就说明不能覆盖。
#include
#define ll long long
using namespace std;
const int MAXN = 2e5 + 5;
int a[MAXN],b[MAXN];
int s[MAXN];
ll sum[MAXN];
int main()
{
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
int n;
scanf("%d",&n);
for(int i = 1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i = 1;i<=n;i++)
{
b[i] = a[i]-a[i-1];
}
b[n+1] = -a[n];
bool flag = 1;
if(b[2] <0 || b[3] < 0) flag = 0;
int sum = 0;
for(int i = 1;i<=n;i++)
{
if(b[i] > 0) sum += b[i];
if(i +3 > n+1) break;
if(b[i+3] < 0) sum += b[i+3];
if(sum < 0) break;
}
if(sum != 0) flag = 0;
printf("Case #%d: %s\n",cat++,(flag ? "Yes" : "No"));
}
}
K - Downgrade
阅读理解题,相当于是升级,一个等级i需要Li经验,现在告诉原始的等级,进行N次操作,每次操作把等级当作经验,原来的经验不管,按照升级规则升级,问最后会到多少。
直接模拟就行,阅读理解题真的烦,还是说我有阅读障碍……
#include
#define ll long long
using namespace std;
const int maxn = 1e5 + 5;
ll a[maxn],sum[maxn];
int main()
{
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
int A,B,n;
scanf("%d%d%d",&A,&B,&n);
for(int i = 1;i<=A;i++)
{
scanf("%lld",&a[i]);
sum[i] = sum[i-1] + a[i];
}
int nowa = A,nowb = B;
for(int i = 0;i<n;i++)
{
int now = lower_bound(sum+1,sum+A+1,nowa) - (sum+1);
int newa = now+1;
int newb = nowa - sum[now];
//cout<
if(newa == nowa && newb == nowb) break;
nowa = newa,nowb = newb;
}
printf("Case #%d: %d-%d\n",cat++,nowa,nowb);
}
}
Gym - 101775L
是个找规律,但是有点麻烦。只推了点:
思考必胜态:S _ _ S ,只要能够造出来这个就行了,所以先手可以必胜的N是7=3+1+3,只要S放在中间点
剩下的之后再推吧。
#include
#define ll long long
using namespace std;
const int MAXN = 2e5 + 5;
int a[MAXN],b[MAXN];
int s[MAXN];
ll sum[MAXN];
int main()
{
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
int n;
scanf("%d",&n);
printf("Case #%d: ",cat++);
if(n & 1 && n > 6)
{
printf("Panda\n");
}
else if( n < 16)
{
printf("Draw\n");
}
else printf("Sheep\n");
}
}
M - World Cup
真正的水题,模拟一下就行了